1. 单文件上传
1. 模板文件
代码语言:javascript复制<!-- csrf为egg所提供的安全机制,需要在模板文件上绑定-->
<form action="/admin/upload/singleUpload?_csrf=<%=csrf%>" method="post" enctype="multipart/form-data">
<ul>
<li>
图片名称:<input type="text" name="title" style="width:300px;"/>
</li>
<li>
图片描述:<textarea name="description" id="" cols="60" rows="8" style="width:300px;"></textarea>
</li>
<!-- 上传文件必须在所有其他的 fields 后面,否则在拿到文件流时可能还获取不到 fields -->
<li>
图片封面:<input type="file" name="cover" style="width:300px;height:26px"/>
</li>
<li>
<button type="submit" class="btn btn-primary">提交</button>
</li>
</ul>
</form>
2. 路由
代码语言:javascript复制// router.js
'use strict';
module.exports = app => {
const { router, controller } = app;
router.post('/admin/upload/singleUpload',controller.admin.upload.singleUpload);
};
3. 控制器
代码语言:javascript复制// app/controller/admin/upload.js
'use strict';
// npm install mz-modules --save
// 此模块解决上传超时卡死
// https://github.com/node-modules/mz-modules
const Pump = require('mz-modules/pump');
const Path = require('path');
const Fs = require('fs');
const Controller = require('egg').Controller;
// 上传控制器
class UploadController extends Controller {
// 单文件上传
async singleUpload() {
// 获取表单提交的数据
let stream = await this.ctx.getFileStream();
// 防止上传空文件
if (!stream.filename) {
return;
}
// 文件名,实际项目中文件名要添加时间戳
let filename = stream.filename.toLowerCase();
// 上传的目录,注意upload目录要存在,实际项目中以云服务器地址为准,入库要替换地址符号
let target = 'app/public/admin/upload/' Path.basename(filename)
// 创建写入流
let writeStream = Fs.createWriteStream(target);
// 上传超过时长会卡死
// stream.pipe(writeStream);
// 上传超过时长不会卡死
await Pump(stream, writeStream);
// 返回上传的信息
this.ctx.body = {
// 表单上传的图片
url: target,
// 表单的其它数据
fields: stream.fields
}
}
}
module.exports = UploadController;
2. 多文件上传
1. 模板文件
代码语言:javascript复制<!-- csrf为egg所提供的安全机制,需要在模板文件上绑定-->
<form action="/admin/upload/multiUpload?_csrf=<%=csrf%>" method="post" enctype="multipart/form-data">
<ul>
<input type="hidden" name="_csrf" value="<%=csrf%>">
<li>
图片名称:<input type="text" name="title" style="width:300px;"/>
</li>
<li>
图片描述:<textarea name="description" id="" cols="60" rows="8" style="width:300px;"></textarea>
</li>
<!-- 上传文件必须在所有其他的 fields 后面,否则在拿到文件流时可能还获取不到 fields -->
<li>
用户头像:<input type="file" name="avatar" style="width:300px;height:26px"/>
</li>
<li>
素材封面:<input type="file" name="cover" style="width:300px;height:26px"/>
</li>
<li>
<button type="submit" class="btn btn-primary">提交</button>
</li>
</ul>
</form>
2. 路由
代码语言:javascript复制// router.js
'use strict';
module.exports = app => {
const { router, controller } = app;
router.post('/admin/upload/multiUpload',controller.admin.upload.multiUpload);
};
3. 控制器
代码语言:javascript复制// app/controller/admin/upload.js
'use strict';
// npm install mz-modules --save
// 此模块解决上传超时卡死
// https://github.com/node-modules/mz-modules
const Pump = require('mz-modules/pump');
const Path = require('path');
const Fs = require('fs');
const Controller = require('egg').Controller;
// 上传控制器
class UploadController extends Controller {
// 多文件上传
async multiUpload() {
// autoFields: true 表示除了文件的其它字段
let parts = this.ctx.multipart({ autoFields: true });
let files = [];
let stream;
// 循环获取数据流
while ((stream = await parts()) != null) {
if (!stream.filename) {
// 多文件上传时,只能break,不能return
break;
}
// 文件名,实际项目中文件名要添加时间戳
let filename = stream.filename.toLowerCase();
// 文件表单的name
let fieldname = stream.fieldname;
// 上传的目录,注意upload目录要存在,实际项目中以云服务器地址为准,入库要替换地址符号
let target = 'app/public/admin/upload/' Path.basename(filename);
let writeStream = Fs.createWriteStream(target);
await Pump(stream, writeStream);
files.push({
[fieldname]: target
});
}
// 返回上传的信息
this.ctx.body = {
// 表单上传的文件
files: files,
// 表单的其它数据,注意放到循环后面,否则拿不到对应的字段
fields: parts.field
}
}
}
module.exports = UploadController;
3. 上传配置
代码语言:javascript复制// config/config.default.js
'use strict';
module.exports = appInfo => {
const config = exports = {};
config.keys = appInfo.name '_1585450669767_9677';
// 上传文件的配置
// https://github.com/eggjs/egg-multipart
config.multipart = {
// 只允许上传的图片格式
whitelist:['.png','.jpg','.jpeg'],
// 文件允许大小
fileSize: '50mb',
}
// 配置两种模板引擎
config.view = {
mapping: {
'.html': 'ejs',
'.nj': 'nunjucks'
}
}
return config
};