egg.js上传文件到ali-oss

413 阅读2分钟

参考:oss-上传本地存储api

1.前端代码

随便建个html文件就开干了~

  <form action="http://127.0.0.1:7001" method="post" enctype="multipart/form-data">
    <input type="file" name="file" id="file" value="" multiple="multiple" />
    <input type="submit" value="提交"/>
  </form>

2.服务端代码

config.default.js配置

 config.security = {
    csrf: {
      enable: false,
    },
  };

  config.multipart = {
    mode: 'file',
    fileExtensions: [ '.apk', '.txt', '.zip', '.jfif', '.pjpeg', '.pjp', '.so', 
    '.xlsx', '.xls', '.csv' ],
  };
  config.oss = {
    // yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
    region: 'oss-cn-hangzhou',
    // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。
    强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
    accessKeyId: '',
    accessKeySecret: '',
    // yourbucketname填写存储空间名称。
    bucket: 'little-orange2022',
  };

csrf:{ enable: false, },的方式是不推荐的,可参考:Egg.js学习与实战系列 · Post请求csrf token问题, 不过我们这里重在测试

mode: 'file' 一定要配置,甚至还可以限制一些可配置的文件类型

config.oss配置在本地是不安全的,应该存放在数据库,通过接口调用,我这里临时弄一下

router

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.post('/', controller.home.index); // 运行后的接口就是http://127.0.0.1:7001
};

文件上传要用post方法哦,因为get请求传输数据的大小最大为2KB,post请求方式要大得多

controller

const Controller = require('egg').Controller;
const path = require('path');

class HomeController extends Controller {
  async index() {
    const { ctx } = this;
    /**
      *  一定要在config.default.js中配置config.multipart = {
      *     mode: 'file',
      *  }
    */
    // 1.获取第一个文件
    const file = ctx.request.files[0];
    // 2.获取文件名
    const fileName = path.basename(file.filename);
    // 3.定义模块名
    const moduleName = 'beautyPics';
    await this.service.common.ossUpload.uploadToOss({ fileName, file, moduleName });
    // 上传到七牛云
  }
}

module.exports = HomeController;

service/common

const OSS = require('ali-oss');
const Service = require('egg').Service;
const fs = require('fs');

module.exports = () => class extends Service {
  async uploadToOss({ fileName, file, moduleName }) {
    const { oss } = this.config; // oss信息可在config中定义
    const client = new OSS(oss);
    const projectName = 'vue3-project'; // 动态获取
    const env = 'beta'; // 动态获取
    const saveFileName = `${projectName}/${env}/${moduleName}/${fileName}`;
    let result;
    try {
      result = await client.put(saveFileName, file.filepath);
    } catch (e) {
      console.log(e);
    } finally {
      // 需要删除临时文件
      fs.unlink(file.filepath, () => {}) // 上传完后,删除文件
    }
    this.ctx.body = {
      url: result.url, // 这里可以写在service也可以controller, 都行吧, 具体内容看需求
    };
  }
};

3.效果

企业微信截图_16644362892376.png

值得注意的是,上传之后,可以把临时文件删除