最近项目在做一个上传头像到nginx搭建的静态服务器,用的是eggJS
下面是整个流程
1. 设置路由
app.router.post('/uploadAvator', checkAdminLogin, app.controller.upload.uploadAvatorController.uploadAvator);
2. controller
'use strict';
const Controller = require('egg').Controller;
const pc = require('../../config/PathConstant'); //这个是我自己写的一个整合路径的config
class uploadAvatorController extends Controller {
async uploadAvator() {
const { ctx } = this;
// 获取 steam
const stream = await ctx.getFileStream();
// 上传基础目录
const uplaodBasePath = pc.avator;
// 调用helper的保存文件插件
const filename = await ctx.helper.handleSaveDoc(uplaodBasePath, 'avator', stream);
// 更新数据库中的文件地址
await ctx.service.upload.uploadAvatorService.uploadAvator(filename);
// 把新的图片地址返回
ctx.body = `http://127.0.0.1:8089/avatar/${filename}`;
}
}
module.exports = uploadAvatorController;
3. Service
'use strict';
const Service = require('egg').Service;
const fs = require('fs');
const pc = require('../../config/PathConstant');
class uploadAvatorService extends Service {
async uploadAvator(avator) {
const { ctx } = this;
// 先获取旧的文件地址,再更新数据库的图片地址,方便等一下删除
const oldAvatar = await ctx.model.Admin.changeAvator(ctx.cookies.get('token', {
signed: false,
}), `http://127.0.0.1:8089/avatar/${avator}`);
// 删除旧的文件
await ctx.service.upload.uploadAvatorService.deleteAvator(oldAvatar.substring(oldAvatar.lastIndexOf('/') + 1, oldAvatar.length));
return;
}
async deleteAvator(avator) {
fs.unlinkSync(`${pc.avator}/${avator}`);
}
}
module.exports = uploadAvatorService;
4. 插件helper
'use strict';
const crypto = require('crypto');
const path = require('path');
const sendToWormhole = require('stream-wormhole');
const fs = require('fs');
module.exports = {
save(basePath, salty, stream) {
// 生成文件名 (时间 + 盐 + 10000以内的随机数 + 文件名后缀的MD5格式hash)
const filename = crypto.createHash('md5').update(Date.now() + ':' + salty + Number.parseInt(Math.random() * 10000) + path.extname(stream.filename)).digest('hex') + path.extname(stream.filename);
const target = path.join(basePath, filename);
// 写入流
const writeStream = fs.createWriteStream(target);
try {
// 写入文件
stream.pipe(writeStream);
} catch (err) {
// 必须将上传的文件流消费掉
sendToWormhole(stream);
throw err;
}
return filename;
},
};