leiwuhen-67's blog leiwuhen-67's blog
首页
    • 《Vue》笔记
    • 《React》笔记
    • 《NodeJs》笔记
    • 《CSS》笔记
    • 《Redis》笔记
    • 基础入门
    • 《Mock》笔记
    • 《MySQL》笔记
    • 《Git》相关
影音视听
收藏
关于
GitHub (opens new window)

我的公众号

首页
    • 《Vue》笔记
    • 《React》笔记
    • 《NodeJs》笔记
    • 《CSS》笔记
    • 《Redis》笔记
    • 基础入门
    • 《Mock》笔记
    • 《MySQL》笔记
    • 《Git》相关
影音视听
收藏
关于
GitHub (opens new window)
  • Express

  • Koa

  • Egg

    • 使用脚手架快速初始化Egg项目
    • 实现接口API并连接mysql数据库
    • 数据库的基本操作,增、删、改、查
    • egg-jwt登录鉴权
    • 上传图片到项目指定文件夹下
    • 上传图片到七牛云
    • 使用ApiDoc生成接口文档
  • Node相关

  • 《NodeJs》笔记
  • Egg
心欲无痕
2023-07-21

上传图片到七牛云

最近在捣鼓 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

编写控制器,在 /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

实现上传图片到七牛云的逻辑,在 /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

在 /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

前端上传代码如下:

<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

至此图片上传到七牛云就大功告成了。

特别说明:

  • AccessKey 和 SecretKey 可以在这里看 (opens new window)
  • 七牛云新建空间后,会有一个默认的测试域名,每个测试域名自创建起 30 个自然日后系统会自动回收,仅供测试使用并且不支持 Https 访问。

因此,如果想长期使用的话,得添加自定义域名,而且添加的自定义域名是需要已备案的域名。

编辑 (opens new window)
上次更新: 7/2/2024, 11:06:45 AM
上传图片到项目指定文件夹下
使用ApiDoc生成接口文档

← 上传图片到项目指定文件夹下 使用ApiDoc生成接口文档→

Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式