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登录鉴权
    • 上传图片到项目指定文件夹下
      • 上传单个文件之Stream模式
    • 上传图片到七牛云
    • 使用ApiDoc生成接口文档
  • Node相关

  • 《NodeJs》笔记
  • Egg
心欲无痕
2023-07-20
目录

上传图片到项目指定文件夹下

# 上传单个文件之 Stream 模式

前端 html 代码:

<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

安装 mz-modules 模块

npm install mz-modules -S
1

在 config.default.js 中配置如下:

config.multipart = {
  // 只允许上传的图片格式,如果上传过程中报错Invalid filename,可能是上传的文件格式不在白名单中,如果是上传excel文件,则白名单中可添加'.xlsx'
  whitelist: [ '.svg', '.png', '.jpg', '.jpeg', '.webp' ],
  // 文件允许大小
  fileSize: '500mb',
  // 上传文件方式
  mode: 'stream',
  // 上传文件个数
  fields: '100',
}
1
2
3
4
5
6
7
8
9
10

在 /app/controller/upload.js 中代码如下:

"use strict";

const controller = require("egg").Controller
const fs = require("fs")
const path = require("path")
const Pump = require('mz-modules/pump');  // 用来将文件存储在本地
const sendToWormhole = require('stream-wormhole');


class uploadController extends controller {
	async index () {
		const { ctx, config } = this;
		const stream = await ctx.getFileStream();
		// 上传图片到指定的目录
		const filename = `image_${Date.now()}.${stream.filename.split('.').pop()}`;
		const target = path.join(__dirname, '../public', filename)
		const writeStream = fs.createWriteStream(target);
		try {
		  await Pump(stream, writeStream);
		} catch(err) {
		  // 必须将上传的文件流消费掉,要不然浏览器响应会卡死
		  await sendToWormhole(stream);
		  throw err;
		}
		// 返回上传成功的信息
		ctx.body = {
		  code: 200,
		  message: '上传成功',
		  data: {
		    filename,
		  },
		};
	}
}

module.exports = uploadController
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

在 /app/router.js 中代码如下:

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.post('/upload', controller.upload.index)
};
1
2
3
4
5
6
7
8
9

现在上传图片后会发现在本地项目的 app/public 文件夹下多了刚上传的图片,使用 http://127.0.0.1:7003 + '/public/' + 图片名即可,例如

上面是将图片上传到已存在的目录文件夹下,如果想要上传到不存在的文件夹,那么需要先新建文件夹,这里需要使用到 mkdirp 插件,这是一款文件夹处理工具,可递归创建目录及其子目录。

安装插件 mkdirp

npm install mkdirp -S
1

引入 mkdirp,创建目录,然后上传,此时 /app/controller/upload.js 文件代码如下:

"use strict";

const controller = require("egg").Controller
const fs = require("fs")
const path = require("path")
const { mkdirp } = require('mkdirp') // 引入文件夹处理工具
const Pump = require('mz-modules/pump');
const sendToWormhole = require('stream-wormhole');


class uploadController extends controller {
	async index () {
		const { ctx, config } = this;
		const stream = await ctx.getFileStream();
		const target = path.join(__dirname, '../public/upload')
		// 3、创建目录
		await mkdirp(target);
		// 上传图片到指定的目录
		const filename = `image_${Date.now()}.${stream.filename.split('.').pop()}`;
		const end = path.join(__dirname, '../public/upload', filename)
		const writeStream = fs.createWriteStream(end);
		try {
		  await Pump(stream, writeStream);
		} catch(err) {
		  // 必须将上传的文件流消费掉,要不然浏览器响应会卡死
		  await sendToWormhole(stream);
		  throw err;
		}
		console.log('end', end)
		// 返回上传成功的信息
		ctx.body = {
		  code: 200,
		  message: '上传成功',
		  data: {
		    file: end  // 返回文件路径
		  },
		};
	}
}

module.exports = uploadController
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

然后就可以上传图片了。

编辑 (opens new window)
上次更新: 7/2/2024, 11:06:45 AM
egg-jwt登录鉴权
上传图片到七牛云

← egg-jwt登录鉴权 上传图片到七牛云→

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