egg-multipart有两种模式:file和stream
el-upload参数传递有两种方式:利用自带参数data和手动添加参数

egg-multipart介绍

一、file 模式下的带参传递

1、egg配置
// config.default.js
  exports.multipart = {
    mode: 'file',
    allowArrayField: true,
    fileSize: '5mb',
  };
2、前端配置
<el-upload
        :action="url"
        :data="uploadData"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :before-remove="handleBeforeRemove"
        :on-success="uploadSuccess"
        :before-upload="beforeUpload"
        :on-change="changeUpload"
        accept=".jpg,.jpeg,.png,.gif,.bmp,.JPG,.JPEG,.PBG,.GIF,.BMP"
      >

其中,uploadData为Object
uploadData: { test: '111111111' },

3、egg后台
// app/controller/upload.js
const Controller = require('egg').Controller;
const fs = require('mz/fs');
const path = require('path');
const oss = require('ali-oss');
const crypto = require('crypto');

module.exports = class extends Controller {
  async upload() {
    const { ctx } = this;
    const file = ctx.request.files[0];

     // 获取传递的参数
    console.log(ctx.request.body);
   

  // 配置阿里云oss
    const client = new oss({
      accessKeyId: this.config.aliyun.accessKeyId,
      accessKeySecret: this.config.aliyun.secretAccessKey,
      bucket: 'xxxx',
      region: 'xxx',
    });

     // 获取后缀
    const extname = path.extname(file.filename)
      .toLocaleLowerCase();

    // 生成唯一的文件名
    const md5 = crypto.createHash('md5');
    const timestamp = (new Date()).getTime(); // 当前时间戳
    const randomNum = Math.ceil(Math.random() * 1000); // 取1000以下的随机数
    const filename = md5.update(path.basename(file.filename, extname) + timestamp + randomNum)
      .digest('hex') + extname;

   
    try {
      // 处理文件,比如上传到云端
      const result = await client.putStream(filename, file.filepath);
      ctx.body = {
        code: 200,
        result
      };
    } catch(e){
      // 需要删除临时文件
      await fs.unlink(file.filepath);
      ctx.body = {
        code: 110,
        msg:e
      };
    }    
  }
};

二、stream 模式

1、egg配置
// config.default.js
  exports.multipart = {
    mode: 'stream',
    allowArrayField: true,
    fileSize: '5mb',
  };
2、前端配置不变
3、egg
const path = require('path');
const sendToWormhole = require('stream-wormhole');
const Controller = require('egg').Controller;

class UploaderController extends Controller {
  async upload() {
    const ctx = this.ctx;
    const stream = await ctx.getFileStream();

  // 获取参数
    console.log(stream.fields);

  if (!stream.filename) {
      ctx.body = {
        code: 110,
        msg: '上传失败,请重新尝试',
      };
      return;
    }


   // 配置阿里云oss
    const client = new oss({
      accessKeyId: this.config.aliyun.accessKeyId,
      accessKeySecret: this.config.aliyun.secretAccessKey,
      bucket: 'xxxx',
      region: 'xxx',
    });

     // 获取后缀
    const extname = path.extname(file.filename)
      .toLocaleLowerCase();

    // 生成唯一的文件名
    const md5 = crypto.createHash('md5');
    const timestamp = (new Date()).getTime(); // 当前时间戳
    const randomNum = Math.ceil(Math.random() * 1000); // 取1000以下的随机数
    const filename = md5.update(path.basename(file.filename, extname) + timestamp + randomNum)
      .digest('hex') + extname;

 
    try {
      const result = await client.putStream(filename, stream);
      ctx.body = {
        code: 200,
        result,       
      };
    } catch (err) {
     console.log(err);
      await sendToWormhole(stream);
      ctx.body = {
        code: 110,
        msg: '上传失败',
      };
    }

    ctx.body = {
      url: result.url,
      // 所有表单字段都能通过 `stream.fields` 获取到
      fields: stream.fields,
    };
  }
}

module.exports = UploaderController;

三、手动传参

如果不通过el-upload的data进行传参,可以手动传参,但是手动传参需要注意一下几点:

1、header设置为formdata格式
headers: {
            'Content-Type': 'multipart/form-data'
          }

axios封装后的请求为:

export function upload(data) {
  return request({
    url: '你的路径',
    method: 'post',
    Headers: { 'Content-Type': 'multipart/form-data' },
    data
  })
}
2、formdata添加参数方式:
        const fileFormData = new FormData()
        fileFormData.append('id', '111111111')
        fileFormData.append('file', this.file_name)

其中,file_name为:file的raw

      changeUpload(file) {
        console.log(file)
        this.file_name = file.raw
      },

欢迎关注,共同交流前端知识~

imageimage

posted on 2021-12-21 01:02  无聊猿  阅读(525)  评论(0编辑  收藏  举报