Multer 是用于处理 multipart/form-data
的 node.js 中间件,主要用于上传文件。 它基于 busboy 之上编写,以实现最高效率。本文将简单介绍怎样使用 multer 上传文件。Multer 会添加一个 body
对象以及 file
或 files
对象到 Express 的 request
对象中。body
对象包含表单的文本域信息,file
或 files
对象包含对象表单上传的文件信息。
安装
npm install multer
API
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) {
...
})
文件信息
每个文件具有下面的信息:
属性 | 描述 | 备注 |
---|---|---|
fieldname | Field name 由表单指定 | |
originalname | 用户计算机上的文件的名称 | |
size | 文件大小(字节单位) | |
destination | 保存在 destination 中的文件名 | DiskStorage |
filename | 文件大小(字节单位) | DiskStorage |
path | 已上传文件的完整路径 | DiskStorage |
multer(opts)
Multer 接受一个 options
对象,其中最基本的是 dest
属性,这将告诉 Multer 将上传文件保存在哪。如果你省略 options
对象,这些文件将保存在内存中,永远不会写入磁盘。
以下是可以传递给 Multer 的选项。
选项 | 描述 |
---|---|
dest/storage | 在哪里存储文件 |
fileFilter | 文件过滤器,控制哪些文件可以被接受 |
limits | 限制上传的数据 |
preservePath | 保存包含文件名的完整文件路径 |
- dest
设置 dest
指定上传文件的目标目录。如果没有设置 storage
,只设置了dest
, Multer 会创建一个 DiskStorage 实例,配置在 dest
下。
- storage
磁盘存储引擎可以让你控制文件的存储。有两个选项可用,destination 和 filename。他们都是用来确定文件存储位置的函数。
- destination
是用来确定上传的文件应该存储在哪个文件夹中。也可以提供一个 string (例如 '/tmp/uploads')。如果没有设置 destination,则使用操作系统默认的临时文件夹。
注意: 如果你提供的 destination
是一个函数,你需要负责创建文件夹。当提供一个字符串,multer 将确保这个文件夹是你创建的。
destination: function (req, file, cb) {
cb(null, 'public/uploads')
},
仅仅设置 destination
成字符串,效果和设置 dest
,不同在 destination
还可以处理文件名。
- filename
用于确定文件夹中的文件名的确定。 如果没有设置 filename,每个文件将设置为一个随机文件名,并且是没有扩展名的。
filename: function (req, file, cb) {
const extName = path.extname(file.originalname)
cb(null, String(Date.now()) + extName)
}
以上代码将为添加与源文件后扩展名,文件后名设置成时间戳。
- fileFilter
设置一个函数来控制什么文件可以上传以及什么文件应该跳过:
upload(req, res, function (err) {
if (err) {
if (err.code === 'LIMIT_FILE_SIZE') {
return next(
customizeError(413, `上传文件不能大于 ${formatSize(fileSize)}`)
);
} else if (err.code === 'LIMIT_FILE_COUNT') {
return next(customizeError(406, `单次上传不能超过${maxCount}个文件`));
}
return next(err);
}
// normal
}
以上代码中,我们在文件上传复制到服务器硬盘前检查了上传文件是否存在,件格式是否正确。
- limits
指定一些数据大小的限制的对象。其中 fileSize
最常用,它可以设置在 multipart 表单中,文件最大长度 (字节单位),默认为无限。在真实上传中,总是会设置 fileSize
来限制文件最大长度的。
limits: {
fileSize: 2 * 1024 * 24
}
以上代码中,我们限制上传文件最大为 2 M。
注意,在真实上传中,推荐在后端限制上传文件的格式和大小,一降低被恶意 DOS 攻击的风险。
错误处理
当遇到一个错误,multer 将会把错误发送给 express。如果你想捕捉 multer 发出的错误,你可以自己调用中间件程序。
const upload = multiple ? instance.array(name, 10) : instance.single(name);
upload(req, res, function (err) {
const file = multiple ? req.files[0] : req.file;
if (err) {
if (err.code === 'LIMIT_FILE_SIZE') {
const error = createError(413);
error.message = `上传文件不能大于 ${fileSize / (1024 * 1024).toFixed(2)} M`;
next(error);
} else {
next(err);
}
} else {
// ...
}
})
这里我们是在中间件程序 upload 处理错误的。设置 limits
的 fileSize 后,如果上传文件大于 2 M,会捕捉 一个 Multer 错误。该错误的 code
和 message
是 Multer 内置的,不是我们想要的的,因此这里进行了覆写。
参考实例
访问 codesandbox 查看完整实例代码。
注意
Multer 不会处理任何非 multipart/form-data
类型的表单数据。
评论 (0)