Multer is a node.js middleware for handling Multer是一个node.js中间件,用于处理multipart/form-data
, which is primarily used for uploading files. multipart/form-data
,主要用于上传文件。It is written on top of busboy for maximum efficiency.它写在busboy机的上面,以达到最大的效率。
NOTE: Multer will not process any form which is not multipart (:Multer不会处理任何非多部分(multipart/form-data
).multipart/form-data
)的表单。
This README is also available in other languages:本自述还提供其他语言版本:
$ npm install --save multer
Multer adds a Multer向请求对象添加body
object and a file
or files
object to the request
object. body
对象和一个file
或files
对象。The body
object contains the values of the text fields of the form, the file
or files
object contains the files uploaded via the form.body
对象包含表单文本字段的值,file
或files
对象包含通过表单上载的文件。
Basic usage example:基本用法示例:
Don't forget the 不要忘记表单中的enctype="multipart/form-data"
in your form.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` filereq.file是`avatar`文件
// req.body will hold the text fields, if there were anyreq.body将保存文本字段(如果有)
})
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// req.files is array of `photos` filesreq.files是`photos`文件的数组
// req.body will contain the text fields, if there were anyreq.body将包含文本字段(如果有)
})
const cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
app.post('/cool-profile', cpUpload, function (req, res, next) {
// req.files is an object (String -> Array) where fieldname is the key, and the value is array of files是一个对象(String -> Array),其中fieldname是键,值是文件数组
//
// e.g.
// req.files['avatar'][0] -> File
// req.files['gallery'] -> Array
//
// req.body will contain the text fields, if there were any将包含文本字段(如果有)
})
In case you need to handle a text-only multipart form, you should use the 如果需要处理纯文本多部分表单,则应使用.none()
method:.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包含文本字段
})
Here's an example on how multer is used an HTML form. 下面是一个关于如何将multer用于HTML表单的示例。Take special note of the 请特别注意enctype="multipart/form-data"
and name="uploaded_file"
fields: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>
Then in your javascript file you would add these lines to access both the file and the body. 然后在javascript文件中添加这些行以访问文件和主体。It is important that you use the 在上载函数中使用表单中的名称字段值非常重要。name
field value from the form in your upload function. This tells multer which field on the request it should look for the files in. 这告诉multer应该在请求的哪个字段中查找文件。If these fields aren't the same in the HTML form and on your server, your upload will fail:如果这些字段在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.file是上面表格中的文件名,这里是'uploaded_file'
// req.body will hold the text fields, if there were any req.body将保存文本字段(如果有)
console.log(req.file, req.body)
});
Each file contains the following information:每个文件包含以下信息:
fieldname |
||
originalname |
||
encoding |
||
mimetype |
||
size |
||
destination |
DiskStorage |
|
filename |
destination destination 文件的名称 |
DiskStorage |
path |
DiskStorage |
|
buffer |
Buffer of the entire fileBuffer |
MemoryStorage |
multer(opts)
Multer accepts an options object, the most basic of which is the Multer接受一个dest
property, which tells Multer where to upload the files. options
对象,其中最基本的是dest
属性,它告诉Multer在哪里上传文件。In case you omit the options object, the files will be kept in memory and never written to disk.如果省略了options对象,文件将保留在内存中,并且永远不会写入磁盘。
By default, Multer will rename the files so as to avoid naming conflicts. 默认情况下,Multer将重命名文件,以避免命名冲突。The renaming function can be customized according to your needs.重命名功能可根据您的需要定制。
The following are the options that can be passed to Multer.以下是可以传递给Multer的选项。
dest or storage |
|
fileFilter |
|
limits |
|
preservePath |
In an average web app, only 在一般的web应用程序中,可能只需要dest
might be required, and configured as shown in the following example.dest
,并按照以下示例所示进行配置。
const upload = multer({ dest: 'uploads/' })
If you want more control over your uploads, you'll want to use the 如果您希望对上载进行更多控制,则需要使用storage
option instead of dest
. storage
选项而不是dest
。Multer ships with storage engines Multer配备存储引擎DiskStorage
and MemoryStorage
; More engines are available from third parties.DiskStorage
和MemoryStorage
;更多引擎可从第三方获得。
.single(fieldname)
Accept a single file with the name 接受名为fieldname
. fieldname
的单个文件。The single file will be stored in 单个文件将存储在req.file
.req.file
中。
.array(fieldname[, maxCount])
Accept an array of files, all with the name 接受文件数组,所有文件的名称均为fieldname
. fieldname
。Optionally error out if more than 如果上载的文件超过maxCount
files are uploaded. maxCount
,则可选择出错。The array of files will be stored in 文件数组将存储在req.files
.req.files
中。
.fields(fields)
Accept a mix of files, specified by 接受由fields
. fields
指定的混合文件。An object with arrays of files will be stored in 带有文件数组的对象将存储在req.files
.req.files
中。
fields
should be an array of objects with name
and optionally a maxCount
. fields
应该是具有name
和maxCount
(可选)的对象数组。Example:例子:
[
{ name: 'avatar', maxCount: 1 },
{ name: 'gallery', maxCount: 8 }
]
.none()
Accept only text fields. 仅接受文本字段。If any file upload is made, error with code "LIMIT_UNEXPECTED_FILE" will be issued.如果上传任何文件,将发出代码为“限制意外文件”的错误。
.any()
Accepts all files that comes over the wire. 接受通过导线传输的所有文件。An array of files will be stored in 文件数组将存储在req.files
.req.files
中。
WARNING: Make sure that you always handle the files that a user uploads. 确保始终处理用户上载的文件。Never add multer as a global middleware since a malicious user could upload files to a route that you didn't anticipate. 永远不要将multer添加为全局中间件,因为恶意用户可能会将文件上载到您没有预料到的路由。Only use this function on routes where you are handling the uploaded files.仅在处理上载文件的路由上使用此功能。
storage
DiskStorage
The disk storage engine gives you full control on storing files to disk.磁盘存储引擎使您能够完全控制将文件存储到磁盘。
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 })
There are two options available, 有两个选项可用:destination
and filename
. destination
和filename
。They are both functions that determine where the file should be stored.它们都是确定文件应存储在何处的函数。
destination
is used to determine within which folder the uploaded files should be stored. destination
用于确定上传文件应存储在哪个文件夹中。This can also be given as a 这也可以作为string
(e.g. '/tmp/uploads'
). string
给出(例如,'/tmp/uploads'
)。If no 如果未指定destination
is given, the operating system's default directory for temporary files is used.destination
,则使用操作系统的临时文件默认目录。
Note: You are responsible for creating the directory when providing 当作为函数提供destination
as a function. destination
时,您负责创建目录。When passing a string, multer will make sure that the directory is created for you.传递字符串时,multer将确保为您创建目录。
filename
is used to determine what the file should be named inside the folder. filename
用于确定文件夹中的文件名称。If no 如果没有指定filename
is given, each file will be given a random name that doesn't include any file extension.filename
,每个文件将被指定一个不包含任何文件扩展名的随机名称。
Note: Multer will not append any file extension for you, your function should return a filename complete with an file extension.Multer不会为您附加任何文件扩展名,您的函数应该返回一个包含文件扩展名的完整文件名。
Each function gets passed both the request (每个函数都会被传递请求(req
) and some information about the file (file
) to aid with the decision.req
)和有关文件(file
)的一些信息,以帮助决策。
Note that 请注意,req.body
might not have been fully populated yet. req.body
可能尚未完全填充。It depends on the order that the client transmits fields and files to the server.这取决于客户端向服务器传输字段和文件的顺序。
For understanding the calling convention used in the callback (needing to pass null as the first param), refer to Node.js error handling要了解回调中使用的调用约定(需要将null
作为第一个参数传递),请参阅Node.js错误处理
MemoryStorage
The memory storage engine stores the files in memory as 内存存储引擎将文件作为Buffer
objects. Buffer
对象存储在内存中。It doesn't have any options.它没有任何选择。
const storage = multer.memoryStorage()
const upload = multer({ storage: storage })
When using memory storage, the file info will contain a field called 使用内存存储时,文件信息将包含一个名为buffer
that contains the entire file.buffer
的字段,该字段包含整个文件。
WARNING: Uploading very large files, or relatively small files in large numbers very quickly, can cause your application to run out of memory when memory storage is used.:当使用内存存储时,上载非常大的文件或快速上载大量相对较小的文件可能会导致应用程序内存不足。
limits
An object specifying the size limits of the following optional properties. 指定以下可选属性的大小限制的对象。Multer passes this object into busboy directly, and the details of the properties can be found on busboy's page.Multer将此对象直接传递给busboy,可以在busboy的页面上找到属性的详细信息。
The following integer values are available:以下整数值可用:
fieldNameSize |
100 bytes | |
fieldSize |
1MB | |
fields |
Infinity | |
fileSize |
Infinity | |
files |
Infinity | |
parts |
Infinity | |
headerPairs |
2000 |
Specifying the limits can help protect your site against denial of service (DoS) attacks.指定限制有助于保护您的站点免受拒绝服务(DoS)攻击。
fileFilter
Set this to a function to control which files should be uploaded and which should be skipped. 将此设置为控制哪些文件应上载,哪些文件应跳过的函数。The function should look like this:函数应如下所示:
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!'))
}
When encountering an error, Multer will delegate the error to Express. 当遇到错误时,Multer会将错误委托给Express。You can display a nice error page using the standard express way.您可以使用标准的Express方式显示一个漂亮的错误页面。
If you want to catch errors specifically from Multer, you can call the middleware function by yourself. 如果您想捕获Multer的错误,您可以自己调用中间件函数。Also, if you want to catch only the Multer errors, you can use the 此外,如果只想捕获Multer错误,可以使用附加到MulterError
class that is attached to the multer
object itself (e.g. err instanceof multer.MulterError
).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.上载时发生Multer错误。
} else if (err) {
// An unknown error occurred when uploading.上载时发生未知错误。
}
// Everything went fine.
})
})
For information on how to build your own storage engine, see Multer Storage Engine.有关如何构建自己的存储引擎的信息,请参阅Multer storage engine。