express 默认并不会处理HTTP请求体中的数据,对于普通请求体(JSON、二进制、字符串)数据,可以使用 body-parse
中间件。而文件上传(multeipart/form-data请求),可以基于请求流处理,也可以使用 formidable
模板或者 Multer
中间件。
multer中间件
Multer
是express官方推出的,用于 Node.js multipart/form-data 请求数据处理的中间件。它可以高速的处理文件上传,但并不处理 multipart/form-data 之外的用户请求。
安装
npm install multer --save
Multer 在解析完请求体后,会向 request 对象添加一个body对象和一个file或者files对象(上传多个文件时使用files对象)。其中body对象包含所提交表单中的文本字段(如果有),而file(或files)对象中包含通过表单上传的文件。
基本用法如下
var express = require("express")
var multer = require("multer")
var upload = multer({dest:'uploads/'})//告诉Multer将上传文件保存在哪里
var app = express()
app.post('/profile',upload.single('avatar'),(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,(req,res,next) => {
//req.files 是一个对象(String -> Array) 键是文件名,值是文件数组
//例如:
//req.files['avatar'][0]->File
//req.files['gallery']->Array
//
//req.body将具有文本域数据,如果存在的话
})
如果需要处理的只是一个文本域的表单,可以使用任何一个Multe方法 single()
、array()
、fields()
下面是一个使用array()
的例子。
var express = require('express')
var app = express()
var multer = require('multer')
var upload = multer()
app.post('/profile',upload.array(),(req,res,next) =>{
//req.body 包含文本
})
API
文件信息
每个文件具有下面的信息:
multer(opts)
Multer
接受一个options对象,其中最基本的是 dest
属性,这将会告诉 Multer
将上传文件保存在哪里,如果省略options 对象,这些文件将保存在内存中,永远不会写入磁盘。
为了避免命名冲突,Multer会修改上传的文件名。这个重命名的功能可以根据需求定制。
以下是可以传递给Multer 的选项:
通常,只需要设置 dest
属性:
var upload = multer({dest:'uploads/'})
如果想在上传时进行更多的控制,可以使用storage
选项替代 dest
。
single(filedname)
接受一个以 fieldname
命名的文件,这个文件的信息保存在 req.file
。
array(filedname[,maxCount])
接受一个以filedname
命名的文件数组。可以配置 maxCount
来限制上传的最大数量。这些文件的信息保存在 req.files
。
fileds(fileds)
接受指定 fileds
的混合文件,这些文件的信息保存在 req.files
。
fileds
应该是一个对象数字,应该具有 name
和可选项 maxCount
属性。
[
{name:'avatar',maxCount:1},
{name:'gallery',maxCount:8}
]
.none()
只接受文本域,如果任何文件上传到这个模式,将发生LIMIT_UNEXPECTED_FILE
错误。 这和 upload.fileds([])
的效果一样。
.any()
接受一切,文件数组将保存在 req.files
。
storage
Multer 具有 DiskStorage
和 MemoryStorage
两个储存引擎;
DiskStorage
磁盘储存引擎控制文件的储存。
var storage = multer.diskStorage({
destination(req,res,cb){
cb(null,'static/uploads')
},
filename(req,res,cb){
cb(null,file.fieldname+'-'+Date.now())
}
})
var upload = multer({storage:storage})
有两个选项可用,destination
和 filename
他们都会用来确定文件储存位置的函数。
distination
是用来确定上传的文件应该储存在哪个文件夹中。也可以提供一个 String
(例如 /static/uploads
) 如果没有设置 destination
,则使用操作默认的临时文件夹。
注意 destination
创建的文件夹如果不存在,将自动创建一个新的文件夹。
filename
用来确定文件夹中的文件名 的确定,如果没有 filename
,每个文件将设置成为一个随机的文件名,并且是没有扩展名的
MemoryStorage
内存储存引擎将文件储在内存中的 Buffer
对象,它没有任何选项
var storage = multer.memoryStorage()
var upload = multer({storage:storage})
当使用内存储存引擎,文件文件信息将包含一个Buffer
字段,里面包含了整个文件数据。
警告: 当你使用内存储存,上传非常大的文件,或者非常多的小文件,会导致应用程序的内存溢出。
limits
一个对象,指定一些数据大小的限制。 可以使用下面这些:
var upload = multer({
storage:storage,
limits:{fieldNameSize:..,
fieldsSize:..
}
})
错误处理机制
当遇到一个错误,multer 将会把错误发送给express。 可以使用一个