注意
此页面由 multer README 生成。Multer

Multer 是一个用于处理 multipart/form-data
的 Node.js 中间件,主要用于文件上传。它基于 busboy 开发,以实现最大效率。
注意:Multer 不会处理任何非 multipart (multipart/form-data
) 类型的表单。
翻译
此 README 也有其他语言版本
العربية | 阿拉伯语 |
简体中文 | 中文 |
Français | 法语 |
한국어 | 韩语 |
Português | 葡萄牙语 (巴西) |
Русский язык | 俄语 |
Español | 西班牙语 |
O’zbek tili | 乌兹别克语 |
Việt Nam | 越南语 |
安装
$ npm install multer
用法
Multer 会在 request
对象上添加一个 body
对象以及一个 file
或 files
对象。body
对象包含表单文本字段的值,file
或 files
对象包含通过表单上传的文件。
基本用法示例
不要忘记在表单中添加 enctype="multipart/form-data"
。
<form action="/profile" method="post" enctype="multipart/form-data">
<input type="file" name="avatar" />
</form>
const express = require('express')
const multer = require('multer')
const upload = multer({ dest: 'uploads/' })
const app = express()
app.post('/profile', upload.single('avatar'), function (req, res, next) {
// req.file is the `avatar` file
// req.body will hold the text fields, if there were any
})
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// req.files is array of `photos` files
// req.body will contain the text fields, if there were any
})
const uploadMiddleware = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
app.post('/cool-profile', uploadMiddleware, function (req, res, next) {
// req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
//
// e.g.
// req.files['avatar'][0] -> File
// req.files['gallery'] -> Array
//
// req.body will contain the text fields, if there were any
})
如果你需要处理一个纯文本的 multipart 表单,你应该使用 .none()
方法
const express = require('express')
const app = express()
const multer = require('multer')
const upload = multer()
app.post('/profile', upload.none(), function (req, res, next) {
// req.body contains the text fields
})
以下是 Multer 在 HTML 表单中的使用示例。请特别注意 enctype="multipart/form-data"
和 name="uploaded_file"
字段
<form action="/stats" enctype="multipart/form-data" method="post">
<div class="form-group">
<input type="file" class="form-control-file" name="uploaded_file">
<input type="text" class="form-control" placeholder="Number of speakers" name="nspeakers">
<input type="submit" value="Get me the stats!" class="btn btn-default">
</div>
</form>
然后,在你的 JavaScript 文件中,你需要添加这些代码行来访问文件和请求体。重要的是,你需要在上传函数中使用表单中 name
字段的值。这会告诉 Multer 应该在请求的哪个字段中查找文件。如果 HTML 表单和服务器上的这些字段不一致,你的上传将会失败
const multer = require('multer')
const upload = multer({ dest: './public/data/uploads/' })
app.post('/stats', upload.single('uploaded_file'), function (req, res) {
// req.file is the name of your file in the form above, here 'uploaded_file'
// req.body will hold the text fields, if there were any
console.log(req.file, req.body)
});
API
文件信息
每个文件包含以下信息
键 | 描述 | 注意 |
---|---|---|
fieldname |
表单中指定的字段名 | |
originalname |
用户计算机上的文件名 | |
encoding |
文件的编码类型 | |
mimetype |
文件的 MIME 类型 | |
size |
文件大小(字节) | |
destination |
文件保存到的文件夹 | DiskStorage |
filename |
文件在 destination 中的名称 |
DiskStorage |
path |
上传文件的完整路径 | DiskStorage |
buffer |
整个文件的 Buffer |
MemoryStorage |
multer(opts)
Multer 接受一个选项对象,其中最基本的是 dest
属性,它告诉 Multer 将文件上传到何处。如果你省略选项对象,文件将保留在内存中,而不会写入磁盘。
默认情况下,Multer 会重命名文件以避免命名冲突。重命名功能可以根据你的需求进行定制。
以下是可以传递给 Multer 的选项。
键 | 描述 |
---|---|
dest 或 storage |
文件存储位置 |
fileFilter |
控制哪些文件被接受的函数 |
limits |
上传数据的限制 |
preservePath |
保留文件的完整路径而不是只保留基本名称 |
在普通的 Web 应用中,可能只需要 dest
,并按以下示例所示进行配置。
const upload = multer({ dest: 'uploads/' })
如果你希望对上传有更多控制,你会希望使用 storage
选项而不是 dest
。Multer 内置了存储引擎 DiskStorage
和 MemoryStorage
;更多引擎可从第三方获取。
.single(fieldname)
接受一个名为 fieldname
的单个文件。该单个文件将存储在 req.file
中。
.array(fieldname[, maxCount])
接受一个文件数组,所有文件都名为 fieldname
。如果上传的文件数量超过 maxCount
,可选地抛出错误。文件数组将存储在 req.files
中。
.fields(fields)
接受由 fields
指定的混合文件。一个包含文件数组的对象将存储在 req.files
中。
fields
应该是一个对象数组,每个对象包含 name
属性和可选的 maxCount
属性。例如
[
{ name: 'avatar', maxCount: 1 },
{ name: 'gallery', maxCount: 8 }
]
.none()
只接受文本字段。如果进行任何文件上传,将发出代码为 “LIMIT_UNEXPECTED_FILE” 的错误。
.any()
接受所有通过网络传输的文件。一个文件数组将存储在 req.files
中。
警告:请确保你总是处理用户上传的文件。切勿将 Multer 添加为全局中间件,因为恶意用户可能会将文件上传到你未预期的路由。仅在处理上传文件的路由上使用此函数。
存储
DiskStorage
磁盘存储引擎使你能够完全控制将文件存储到磁盘。
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/tmp/my-uploads')
},
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
cb(null, file.fieldname + '-' + uniqueSuffix)
}
})
const upload = multer({ storage: storage })
有两个可用选项:destination
和 filename
。它们都是确定文件存储位置的函数。
destination
用于确定上传文件应存储在哪个文件夹中。它也可以作为一个 string
提供(例如 '/tmp/uploads'
)。如果没有提供 destination
,则使用操作系统的默认临时文件目录。
注意:当将 destination
作为函数提供时,你有责任创建目录。当传递字符串时,Multer 将确保为你创建目录。
filename
用于确定文件在文件夹中的命名。如果没有提供 filename
,每个文件将被赋予一个不包含任何文件扩展名的随机名称。
注意:Multer 不会为你添加任何文件扩展名,你的函数应该返回一个包含文件扩展名的完整文件名。
每个函数都会传递请求 (req
) 和一些关于文件的信息 (file
),以帮助做出决定。
请注意,req.body
可能尚未完全填充。这取决于客户端向服务器传输字段和文件的顺序。
要了解回调中使用的调用约定(需要将 null 作为第一个参数传递),请参阅 Node.js 错误处理
MemoryStorage
内存存储引擎将文件作为 Buffer
对象存储在内存中。它没有任何选项。
const storage = multer.memoryStorage()
const upload = multer({ storage: storage })
当使用内存存储时,文件信息将包含一个名为 buffer
的字段,其中包含整个文件。
警告:当使用内存存储时,上传非常大的文件,或者非常快速地上传大量相对较小的文件,可能会导致你的应用程序内存耗尽。
limits
一个对象,用于指定以下可选属性的大小限制。Multer 直接将此对象传递给 busboy,属性的详细信息可以在 busboy 的页面上找到。
以下整数值可用
键 | 描述 | 默认值 |
---|---|---|
fieldNameSize |
最大字段名大小 | 100 字节 |
fieldSize |
最大字段值大小(字节) | 1MB |
fields |
最大非文件字段数 | 无限 |
fileSize |
对于 multipart 表单,最大文件大小(字节) | 无限 |
files |
对于 multipart 表单,最大文件字段数 | 无限 |
parts |
对于 multipart 表单,最大部件数(字段 + 文件) | 无限 |
headerPairs |
对于 multipart 表单,要解析的最大 header key=>value 对数 | 2000 |
指定限制可以帮助保护你的网站免受拒绝服务 (DoS) 攻击。
fileFilter
将此设置为一个函数,以控制哪些文件应该被上传,哪些应该被跳过。该函数应如下所示:
function fileFilter (req, file, cb) {
// The function should call `cb` with a boolean
// to indicate if the file should be accepted
// To reject this file pass `false`, like so:
cb(null, false)
// To accept the file pass `true`, like so:
cb(null, true)
// You can always pass an error if something goes wrong:
cb(new Error('I don\'t have a clue!'))
}
错误处理
当遇到错误时,Multer 会将错误委托给 Express。你可以使用 标准的 Express 方式显示一个友好的错误页面。
如果你想专门捕获来自 Multer 的错误,你可以自己调用中间件函数。此外,如果你只想捕获 Multer 错误,你可以使用附加在 multer
对象本身的 MulterError
类(例如 err instanceof multer.MulterError
)。
const multer = require('multer')
const upload = multer().single('avatar')
app.post('/profile', function (req, res) {
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
// A Multer error occurred when uploading.
} else if (err) {
// An unknown error occurred when uploading.
}
// Everything went fine.
})
})
自定义存储引擎
有关如何构建自己的存储引擎的信息,请参阅 Multer 存储引擎。