Egg.js (三) 文件上传 阿里云OSS

在三年前前也写过关于阿里云OSS上传的,但是当时使用的Express。
Node.js阿里云OSS文件上传
这次使用的Egg.js,在实际操作中也发现阿里云OSS的文档和官网操作有了一些变化了。
在下面的操作需要有先看看如下文档:
Egg.js-获取上传的文件
对象存储 OSS > SDK 参考 > Node.js
对象存储 OSS > 开发指南 > 访问域名(Endpoint) > 访问域名和数据中心
egg-multipart

config/config.default.js文件中启用 file 模式:

const config = exports = {
    // 文件上传
    // https://eggjs.org/zh-cn/basics/controller.html#获取上传的文件
    multipart: {
      mode: 'file',
      fileSize: '50mb', // 接收文件大小
      whitelist: [  // 允许接收的文件类型
        '.png',
        '.jpg'
      ],
    }
 }

config/config.default.js中解决跨域问题

config.cors = {
  origin:'*',
  allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS'
};

编写前端测试代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<form method="POST" action="http://localhost:7001/alioss/upload" enctype="multipart/form-data">
		  file: <input name="file" type="file" />
		  <button type="submit">Upload</button>
		</form>
	</body>
</html>

后端代码

'use strict';

// https://help.aliyun.com/document_detail/32068.html

const Controller = require('egg').Controller;
const fs = require('mz/fs');
let OSS = require('ali-oss');

let aliInfo = {
  // https://help.aliyun.com/document_detail/31837.html
  region: 'oss-cn-shenzhen',
  bucket: 'qxxxxxxxxx',
  accessKeyId: 'LxxxxxxxxxxxxB',
  accessKeySecret: 'Ixxxxxxxxxxxxxxxxi'
}

let client = new OSS(aliInfo);

class AliOssController extends Controller {
  async upload() {
    const { ctx } = this;
    const file = ctx.request.files[0];
    let result;
    try {
      // https://help.aliyun.com/document_detail/111265.html
      // 处理文件,比如上传到云端
      result = await client.put(file.filename, file.filepath);
    } finally {
      // 需要删除临时文件
      await fs.unlink(file.filepath);
    }
    ctx.body = {
      url: result.url,
      // 获取所有的字段值
      requestBody: result,
    };
  }
}

module.exports = AliOssController;

注册路由

router.post('/alioss/upload', controller.alioss.upload);

到这里整个过程就完毕了。

微信小程序也可使用

上面的后端上传接口在微信小程序中也是可以正常使用的,亲测有效。

wx.chooseImage({
  count: 1,
  sizeType: ['original', 'compressed'],
  sourceType: ['album', 'camera'],
  success (res1) {
    const tempFilePaths = res1.tempFilePaths[0]
    // tempFilePath可以作为img标签的src属性显示图片
    wx.uploadFile({
      url: 'http://localhost:7001/alioss/upload',
      filePath: tempFilePaths,
      name: 'file',
      success (res) {
      },
      fail (res) {
      }
    })
  }
})
图片上传报错; 报错内容: 2017-09-15 17:13:44,493 INFO 1474 [master] egg started on http://127.0.0.1:7001 (1976ms) field: multiplefile filename: 111.png encoding: 7bit mime: image/png 2017-09-15 17:13:53,619 ERROR 1476 [-/::1/-/27ms POST /upload?_csrf=aUvmihGq--KleIqqIGZRLYsXAM989DojoFUw] nodejs.TypeError: ctx.oss.put is not a function at HomeController.upload (/Users/lixiuming/egg-example/app/controller/home.js:52:48) at next (native) at onFulfilled (/Users/lixiuming/egg-example/node_modules/co/index.js:65:19) at process._tickCallback (internal/process/next_tick.js:109:7) pid: 1476 controller: * upload() { const ctx = this.ctx; const parts = ctx.multipart(); let part; while ((part = yield parts) != null) { if (part.length) { // 如果是数组的话是 filed console.log('field: ' + part[0]); console.log('value: ' + part[1]); console.log('valueTruncated: ' + part[2]); console.log('fieldnameTruncated: ' + part[3]); } else { if (!part.filename) { // 这时是用户没有选择文件就点击了上传(part 是 file stream,但是 part.filename 为空) // 需要做出处理,例如给出错误提示消息 return; } // part 是上传文件流 console.log('field: ' + part.fieldname); console.log('filename: ' + part.filename); console.log('encoding: ' + part.encoding); console.log('mime: ' + part.mime); // 文件处理,上传到云存储等等 let result; try { result = yield ctx.oss.put('egg-multipart-test/' + part.filename, part); } catch (err) { // 必须将上传文件流消费掉,要不然浏览器响应会卡死 // yield sendToWormhole(stream); throw err; } console.log(result); } } console.log('and we are done parsing the form!'); }
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页