主题
今天的主题是使用eggjs实现上传文件到七牛云平台。
安装依赖
1.安装七牛
npm install qiniu
再安装如下依赖,后面会用到
npm install await-stream-ready stream-wormhole
2.创建路由
路由创建,可阅读egg(二):router.js实现模块化配置实现路由模块化配置。
// 上传文件
router.post('/xiaobuAdmin/common/upload', controller.common.upload);
3.创建控制器
控制器创建
// 上传文件
async upload() {
const { ctx } = this;
const data = await ctx.service.common.uploadFiles();
if (data) {
ctx.body = data;
} else {
ctx.body = {
message: '上传失败',
};
}
}
4.创建服务
服务创建
const Service = require('egg').Service;
const fs = require('fs');
const path = require('path');
const qiniu = require('qiniu');
const awaitWriteStream = require('await-stream-ready').write;
const sendToWormhole = require('stream-wormhole');
const md5 = require('md5');
const bucket = 'XXX'; // 要上传的空间名
const imageUrl = 'XXX'; // 空间绑定的域名
const accessKey = 'Access Key'; // Access Key
const secretKey = 'Secret Key'; // Secret Key
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
const options = {
scope: bucket,
};
const putPolicy = new qiniu.rs.PutPolicy(options);
const uploadToken = putPolicy.uploadToken(mac);
const config = new qiniu.conf.Config();
config.zone = qiniu.zone.Zone_z2;
class CommonService extends Service {
async uploadFiles() {
const { ctx } = this;
const stream = await ctx.getFileStream();
const filename =
md5(stream.filename) + path.extname(stream.filename).toLocaleLowerCase();
const localFilePath = path.join(__dirname, '../public/uploads/', filename);
const writeStream = fs.createWriteStream(localFilePath);
try {
await awaitWriteStream(stream.pipe(writeStream));
const formUploader = new qiniu.form_up.FormUploader(config);
const putExtra = new qiniu.form_up.PutExtra();
const imgSrc = await new Promise((resolve, reject) => {
formUploader.putFile(
uploadToken,
filename,
localFilePath,
putExtra,
(respErr, respBody, respInfo) => {
if (respErr) {
reject(respErr);
}
if (respInfo.statusCode === 200) {
resolve(imageUrl + respBody.key);
} else {
reject(respInfo);
}
// 上传之后删除本地文件
fs.unlinkSync(localFilePath);
}
);
});
if (imgSrc !== '') {
return {
url: imgSrc,
};
}
return false;
} catch (err) {
// 如果出现错误,关闭管道
await sendToWormhole(stream);
return err;
}
}
}
module.exports = CommonService;
注意事项
上述创建服务的代码中,存在 ../public/uploads 文件夹,因此我们需要提前先把文件夹创建好,否则会报错,无法成功上传。