egg-multipart有兩種模式:file和stream
el-upload參數傳遞有兩種方式:利用自帶參數data和手動添加參數
一、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
},
歡迎關注,共同交流前端知識~