multer解析文件上传

author author     2022-08-27     495

关键词:

Express默认并不处理HTTP请求体中的数据,对于普通请求体(JSON、二进制、字符串)数据,可以使用body-parser中间件。而文件上传(multipart/form-data请求),可以基于请求流处理,也可以使用formidable模块或Multer中间件。

1. multer中间件

Multer是Express官方推出的,用于Node.jsmultipart/form-data请求数据处理的中间件。

它基于busboy构建,可以高效的处理文件上传,但并不处理multipart/form-data之外的用户请求。

2. 安装

1
npm install multer --save

3. 使用

Multer在解析完请求体后,会向Request对象中添加一个body对象和一个file或files对象(上传多个文件时使用files对象 )。其中,body对象中包含所提交表单中的文本字段(如果有),而file(或files)对象中包含通过表单上传的文件。

基本使用示例如下:

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
var express = require(‘express‘)
var multer = require(‘multer‘)
var upload = multer({ dest: ‘uploads/‘ })
 
var app = express()
 
app.post(‘/profile‘, upload.single(‘avatar‘), function (req, res, next) {
 // req.file 是 `avatar` 文件
 // req.body 对象中是表单中提交的文本字段(如果有)
})
 
app.post(‘/photos/upload‘, upload.array(‘photos‘, 12), function (req, res, next) {
 // req.files 是 `photos` 文件数组
 // req.body 对象中是表单中提交的文本字段(如果有)
})
 
var cpUpload = upload.fields([{ name: ‘avatar‘, maxCount: 1 }, { name: ‘gallery‘, maxCount: 8 }])
app.post(‘/cool-profile‘, cpUpload, function (req, res, next) {
 // req.files 是一个对象 (String -> Array),文件的字段名是其 key,文件数组是 key的值
 //
 // 如:
 // req.files[‘avatar‘][0] -> File
 // req.files[‘gallery‘] -> Array
 //
 // req.body 对象中是表单中提交的文本字段(如果有)
})

在使用中,如果仅需要处理multipart表单中的文本字段,可以使用multer中的.single() 、 .array()fields()方法。

如,可以像下面这样使用.array()方法:

1
2
3
4
5
6
7
8
var express = require(‘express‘)
var app = express()
var multer = require(‘multer‘)
var upload = multer()
 
app.post(‘/profile‘, upload.array(), function (req, res, next) {
 // req.body 中包含文本字段
})

4. multer的API

4.1 文件对象

multer解析完上传文件后,会被保存为一个包含以下字段的对象:

       fieldname - 表单提交的文件名(input控件的name属性)

       originalname - 文件在用户设备中的原始名称

       encoding - 文件的编码类型

       mimetype - 文件的Mime类型

       size - 文件的大小

       destination - 文件的保存目录(DiskStorage)

       filename - 文件在destination中的名称(DiskStorage)

       path - 上传文件的全路径(DiskStorage)

       buffer - 文件对象的Buffer(MemoryStorage)

4.2 方法

multer(opts) - 创建对象

引用multer模块后,我们会获取到一个顶级方法。该方法是一个工厂函数,可以使用这个方法创建Multer对象。它接受一个选项对象,最基本的选项是dest,它告诉 Multer 文件的存储位置。如果忽略该选项,文件会被保存在内存中,并且永远不会写入硬盘中。

默认情况下,Multer会对文件进行重命令,以避免名称冲突。重命名函数,可以按需要自定义。

Multer的选项对象中可以包含以下值:

       dest或storage - 文件存储位置

       fileFilter - 函数,控制可上传的文件类型

       limits - 上传数据限制(文件大小)

在一般的Web应用中,只有dest选项需要设置。使用示例如下:

1
var upload = multer({ dest: ‘uploads/‘ })

如果需要对上传文件做更多控制,可以使用storage代替dest,Multer会将存储引擎由DiskStorage(硬盘存储)切换为MemoryStorage(内存存储)。

创建multer对象后,我们可以使用以下实例来接收上传文件:

.single(fieldname) - 单个文件上传

接收一个名为fieldname的上传文件,所上传的文件会被保存在req.file。

.array(fieldname[, maxCount]) - 多个文件上传

接收名为fieldname的,多个上传文件数组。可选参数maxCount表示可接受的文件数量,上传文件数超出该参数指定的数据后会抛出一个错误。文件数组会被保存在req.files中。

.fields(fields) - 多个文件上传

接收通过fields指定的多个上传文件。文件数组对象会被保存在req.files中。

fields是一个包含对象的数组,对象中会包含name和maxCount两个属性:

1
2
3
4
[
 { name: ‘avatar‘, maxCount: 1 },
 { name: ‘gallery‘, maxCount: 8 }
]

.none() - 仅解析文本字段

仅解析文本字段。如果请求中有任何上传文件,会触发‘LIMIT_UNEXPECTED_FILE‘错误。这个方法与upload.fields([])类似。

.any() - 接收所有文件

接收请求中的所有文件。上传文件数组会被保存在req.files中。

4.3 选项参数

storage - 存储引擎

该选项有以下两个可选项:

       DiskStorage - 硬盘存储

       MemoryStorage - 内存存储

.diskStorage(obj)与硬盘存储

硬盘存储引擎提供了将文件存储到磁盘的完全控制:

1
2
3
4
5
6
7
8
9
10
var storage = multer.diskStorage({
 destination: function (req, file, cb) {
 cb(null, ‘/tmp/my-uploads‘)
 },
 filename: function (req, file, cb) {
 cb(null, file.fieldname + ‘-‘ + Date.now())
 }
})
 
var upload = multer({ storage: storage })

.diskStorage()方法提供了文件存储位置控制权限,该方法接收一个对象参数,其中包含两destination和filename两个属性。

destination用于设置文件的存储目录,可以是一个函数或字符串。若未提供该参数,将使用系统的临时目录。

filename用于设置文件名。若未提供该参数,将使用一个随机字符串,且文件名中不包含扩展名。

.memoryStorage()与内存存储

内存存储引擎会以Buffer的形式将文件保存在内存中。该方法没有任何参数:

1
2
var storage = multer.memoryStorage()
var upload = multer({ storage: storage })

limits - 文件尺寸

该选项用于设置文件尺寸,Multer 会将这个对象传递至busboy中。limits对象中可以包含以下可选值:

       fieldNameSize - 字段名最大尺寸。默认值:100 bytes

       fieldSize - 字段值最大尺寸。默认值:1MB

       fields - 非文件字段的最大数量。默认值:Infinity

       fileSize - multipart 表单中,文件的最大尺寸。默认值:Infinity

       files - multipart 表单中,文件最大数量。默认值:Infinity

       parts - multipart 表单中,最大组件(fields+files)数量。默认值:Infinity

       headerPairs - 默认值:2000

fileFilter - 文件筛选

fileFilter用于控制要哪些文件是可接受的,哪些是要被拒绝的。使用形式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function fileFilter (req, file, cb) {
 
 // 需要调用回调函数 `cb`,
 // 并在第二个参数中传入一个布尔值,用于指示文件是否可接受
 
 // 如果要拒绝文件,上传则传入 `false`。如:
 cb(null, false)
 
 // 如果接受上传文件,则传入 `true`。如:
 cb(null, true)
 
 // 出错后,可以在第一个参数中传入一个错误:
 cb(new Error(‘I don‘t have a clue!‘))
}

使用 multer 上传的文件存储在云端后如何删除?

】使用multer上传的文件存储在云端后如何删除?【英文标题】:Howtodeletefilesuploadedwithmulteroncetheyarestoredinthecloud?【发布时间】:2021-01-1211:24:47【问题描述】:我使用multer将文件上传到Express服务器。它们被解析并存储到Cloudinary。... 查看详情

使用 multer 上传多个文件,但来自不同的字段?

】使用multer上传多个文件,但来自不同的字段?【英文标题】:Uploadingmultiplefileswithmulter,butfromdifferentfields?【发布时间】:2016-07-0522:35:13【问题描述】:如何让multer接受来自多个文件类型字段的文件?我有以下代码上传单个文件... 查看详情

使用multer上传时如何限制文件大小?

】使用multer上传时如何限制文件大小?【英文标题】:Howtolimitthefilesizewhenuploadingwithmulter?【发布时间】:2016-04-1408:14:28【问题描述】:我正在用multer制作一个简单的文件上传系统:varmaxSize=1*1000*1000;varstorage=multer.diskStorage(destinatio... 查看详情

如何从 multer 访问上传的文件?

】如何从multer访问上传的文件?【英文标题】:Howtoaccessuploadedfilefrommulter?【发布时间】:2017-08-3020:32:48【问题描述】:我可以将图片上传到S3。现在,如果选择的文件是.gif,我希望能够将.gif文件转换为.mp4并将转换后的文件上传... 查看详情

无法使用 NestJs 和 Multer 上传文件

】无法使用NestJs和Multer上传文件【英文标题】:NotabletouploadfileusingNestJsandMulter【发布时间】:2021-11-0917:52:48【问题描述】:我正在尝试使用Nestjs将文件上传到awss3存储桶@Post(\'uploadfile/:bucketName\')@UseInterceptors(FileInterceptor(\'file\'))asy... 查看详情

Multer-s3 在手机上上传空文件

】Multer-s3在手机上上传空文件【英文标题】:Multer-s3Uploadingemptyfilesonmobile【发布时间】:2018-08-0316:47:55【问题描述】:我正在使用Angular和multer-s3将文件从Angular应用程序上传到节点服务器。在桌面上一切正常,但由于某种原因,... 查看详情

multer上传图片

app.jsvarfs=require(‘fs‘);varexpress=require(‘express‘);varmulter=require(‘multer‘)varapp=express();varstorage=multer.diskStorage({ //设置上传后文件路径,uploads文件夹会自动创建。 destination:function(req,file,cb){ cb( 查看详情

Multer 多次上传失败,初始上传 3 次

】Multer多次上传失败,初始上传3次【英文标题】:Multermultipleuploadsfailandinitialuploadcomesinthreetimes【发布时间】:2017-02-2700:47:46【问题描述】:第一个文件成功通过后,我无法上传第二个文件。使用这条路线...varmulter=require(\'multer\'... 查看详情

node之post提交上传

post文件上传multer中间件在node中express为了性能考虑采用按需加载的方式,引入各种中间件来完成需求,平时解析post上传数据时候,是用body-parse。但这个中间件有缺点,只能解析post的文本内容,(application/x-www-form-urlencoded)不能... 查看详情

nodejs进阶:基于express+multer的文件上传

安装组件npminstallexpressmulter--save服务端代码server.jsvarExpress=require(‘express‘);varmulter=require(‘multer‘);varbodyParser=require(‘body-parser‘);varapp=Express();app.use(bodyParser.json());//multer提供了sto 查看详情

在使用 Multer 将文件上传到文件夹之前删除和创建文件夹

】在使用Multer将文件上传到文件夹之前删除和创建文件夹【英文标题】:deleteandcreatefolderbeforeuploadingfilesintothefolderusingMulter【发布时间】:2019-05-1511:53:48【问题描述】:我正在尝试使用multer将文件上传到文件夹中,它工作正常。... 查看详情

Multer 没有将文件上传到服务器

】Multer没有将文件上传到服务器【英文标题】:Multerisnotuploadingafiletotheserver【发布时间】:2020-12-1609:11:09【问题描述】:我正在尝试通过Multer将文件上传到服务器。这段代码所做的只是创建文件夹而不是文件。我也尝试使用github... 查看详情

使用 Multer 上传文件,而不知道它们的字段名

】使用Multer上传文件,而不知道它们的字段名【英文标题】:UploadingfilesusingMulter,withoutknowingthetheirfieldname【发布时间】:2015-10-3102:29:13【问题描述】:看完这篇文章:http://lollyrock.com/articles/express4-file-upload/我发现,当您不知道要... 查看详情

如何使用 multer 或 body-parser 上传文件

】如何使用multer或body-parser上传文件【英文标题】:Howtouploadfileusingmulterorbody-parser【发布时间】:2016-07-1204:29:20【问题描述】:我是一名NodeJS初学者,正在阅读《使用MongoDB和NodeJS进行Web开发》一书。我被“multer”困在第6章。当... 查看详情

nodejs multer文件上传,路径包含双斜杠

】nodejsmulter文件上传,路径包含双斜杠【英文标题】:nodejsmulterfileupload,pathcontainsdoubleslashes【发布时间】:2017-09-2919:54:21【问题描述】:我正在通过nodejs和multer模块上传图片,这是我正在使用的代码:app.post(\'/upload\',upload.single(\... 查看详情

使用带有 expressjs 的 multer 上传文件时的错误处理

】使用带有expressjs的multer上传文件时的错误处理【英文标题】:Errorhandlingwhenuploadingfileusingmulterwithexpressjs【发布时间】:2015-08-3013:53:23【问题描述】:我正在使用multer将文件保存在通过express和nodejs开发的服务器上。我正在使用... 查看详情

用于文件上传的 JWT 令牌和 Multer(节点)

】用于文件上传的JWT令牌和Multer(节点)【英文标题】:JWTTokenandMulterforFileUploads(Node)【发布时间】:2016-05-0316:35:21【问题描述】:我需要一些帮助来弄清楚如何让它工作——我已经测试并在我的“/用户”路由上使用了JWT身份验... 查看详情

nodejs+multer+ajax文件上传

前端html代码+ajax代码  form表单(无需指定action)<formenctype="multipart/form-data"method="post"class="upload-cont"><inputtype="file"name="files1"class="files1"><inputtype="text"name="username"class= 查看详情