egg-multipart + el-upload 實現帶參圖片上傳至阿里雲OSS


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM