上传图片到七牛云
最近在捣鼓 Egg.js 的图片上传功能,考虑到七牛云的比较划算,因此想拿七牛云练练手。还没注册的可以先去注册 (opens new window)
首先安装依赖 qiniu, 详情见 Node.js SDK (opens new window)
npm install qiniu
1
还需要安装三个依赖,后续会用到:
// await-stream-ready:能够使用await进行文件的读写操作。
// stream-wormhole:在文件上传出现异常时能够把流消耗掉。
npm install await-stream-ready stream-wormhole md5 -S
1
2
3
2
3
编写控制器,在 /app/controller/upload.js 中代码如下:
"use strict";
const controller = require("egg").Controller
class uploadController extends controller {
async index () {
const { ctx, config } = this;
const data = await ctx.service.uploadUtils.uploadFiles();
if (data) {
ctx.body = data;
} else {
ctx.body = {
message:"上传失败"
}
}
}
}
module.exports = uploadController
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
实现上传图片到七牛云的逻辑,在 /app/service/uploadUtils.js 中代码如下:
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 = "test-demo666"; //要上传的空间名
const imageUrl = ""; // 空间绑定的域名
const accessKey = ""; //Access Key
const secretKey = ""; //Secret Key
let config = new qiniu.conf.Config();
config.zone = qiniu.zone.Zone_z2; // 存储区域,华东:z0, 华北:z1,华南:z2,华美:na0,东南亚:as0
class uploadUtilsService 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/upload", filename);
const writeStream = fs.createWriteStream(localFilePath);
const mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
const options = {
scope: bucket,
// expires: 7200, // 默认情况下,在不指定上传凭证的有效时间情况下,默认有效期为1个小时
};
const putPolicy = new qiniu.rs.PutPolicy(options);
const uploadToken = putPolicy.uploadToken(mac);
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("");
}
if (respInfo.statusCode == 200) {
resolve(imageUrl + respBody.key);
} else {
reject("");
}
// 上传之后删除本地文件
fs.unlinkSync(localFilePath);
}
);
});
if (imgSrc !== "") {
return {
url: imgSrc
};
} else {
return false;
}
} catch (err) {
//如果出现错误,关闭管道
await sendToWormhole(stream);
return false;
}
}
}
module.exports = uploadUtilsService
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
在 /app/router.js 中代码如下:
'use strict';
/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => {
const { router, controller, middleware } = app;
router.post('/upload', controller.upload.index)
};
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
前端上传代码如下:
<form
method="POST"
action="http://127.0.0.1:7003/upload"
enctype="multipart/form-data"
>
title: <input name="title" /> file: <input name="file" type="file" />
<button type="submit">Upload</button>
</form>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
至此图片上传到七牛云就大功告成了。
特别说明:
- AccessKey 和 SecretKey 可以在这里看 (opens new window)
- 七牛云新建空间后,会有一个默认的测试域名,每个测试域名自创建起 30 个自然日后系统会自动回收,仅供测试使用并且不支持 Https 访问。
因此,如果想长期使用的话,得添加自定义域名,而且添加的自定义域名是需要已备案的域名。
编辑 (opens new window)
上次更新: 7/2/2024, 11:06:45 AM