安装
npm install multer --save
为了方便演示,本文内容涉及express的模板引擎art-template
使用
index.html模板,注意一定要写enctype="multipart/form-data"
,和 input 标签的name
属性,
name是multer接收文件重要标识
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="/doPost" method="post" enctype="multipart/form-data">
<input type="text" name="name" id="name" />
<br/>
<input type="file" name="pic" id="pic" />
<br/>
<button type="submit">提交</button>
</form>
</body>
</html>
处理请求express.js
const express = require('express')
const multer = require('multer')
const path = require('path')
// 控制上传文件的存储位置,存储名称
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/uploads')
},
// destination: 'public/uploads',
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const upload = multer({ storage: storage })
const app = express();
// 设置 art-template 模板引擎
app.engine('html', require('express-art-template'))
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'html')
// 设置路由,渲染模板
app.get('/index', (req, res) => {
res.render('index', {})
})
// 监听post请求,upload.single 只接受单个文件上传
app.post('/doPost',upload.single('pic'),(req,res)=>{
var body = req.body;
console.log(body.files);
res.send({
body: req.body,
file: req.file
})
})
app.listen(3000)
运行代码,浏览器输入
localhost:3000/index
文本框输入test,选择文件上传,提交,浏览器返回如下图所示:
文件成功上传!看看这个过程做了什么:首先引入multer
模块,调用模块的diskStorage()
的方法,控制上传文件的位置和名称,该方法接收两个函数参数:
destination
:用于确定应将上传的文件存储在哪个文件夹中。特别的是,如果直接这样子返回字符串destination: 'public/uploads'
,目录不存在的话,multer将为您安全创建目录;若不返回字符串,则必须要保证存在这样的目录,否则应用程序报错。filename
:用于确定文件夹内的文件应该命名为什么。如果没有指定文件名,每个文件将被指定一个不包括任何文件扩展名的随机名称,这里使用了file.originalname
作为文件名,该属性下文会提及。
然后,multer 使用这个控制方法返回的对象创建了multer
对象,在监听请求时,使用中间件接收表单上传的文件。upload.single('pic')
接收单个文件,参数对应着 form 表单的 name 属性。
再来看看浏览器给我们返回了什么信息,
{
"body":{"name":"test"},
"file":{
"fieldname":"pic",
"originalname":"前端路线.jpg",
"encoding":"7bit",
"mimetype":"image/jpeg",
"destination":"public/uploads",
"filename":"前端路线.jpg",
"path":"public\\uploads\\前端路线.jpg",
"size":249147
}
}
multer 将表单的文本信息挂载在了 req 的 body 属性,而上传的文件信息则挂载在了 req 的 file 属性。所以可以在destination
和filename
这两个方法中根据 req 对象挂载的信息做一些其他的逻辑处理。上述代码,将 originalname 作为了文件名存储了在 public/uploads 中。
Key | Description | Note |
---|---|---|
fieldname | Field name 由表单指定 | |
originalname | 用户计算机上的文件的名称 | |
encoding | 文件编码 | |
mimetype | 文件的 MIME 类型 | |
size | 文件大小(字节单位) | |
destination | 保存路径 | DiskStorage |
filename | 保存在 destination 中的文件名 | DiskStorage |
path | 已上传文件的完整路径,基于项目根目录 | DiskStorage |
buffer | 一个存放了整个文件的 Buffer | MemoryStorage |
补充:
multer()方法是一个工厂函数,可以使用这个方法创建 Multer 对象。它接受一个选项对象,最基本的选项是 dest ,它告诉 Multer 文件的存储位置。如果忽略该选项,文件会被保存在内存中,并且永远不会写入硬盘中。默认情况下,Multer会对文件进行重命名,以避免名称冲突。
Multer的选项对象中可以包含以下值:
- dest或storage - 文件存储位置
- fileFilter - 函数,控制可上传的文件类型
- limits - 上传数据限制(文件大小)
在一般的Web应用中,只有dest选项需要设置。使用示例如下:
const upload = multer({ dest: 'public/uploads' })
上传多个文件
上传多个文件使用
upload.array('name',maxCount)
upload.fields([{name: 'name',maxCount:NUMBER}])
当多文件上传,文件信息将会挂载在req.files
上,注意files有s,而不是 file 。
array
upload.array('name',maxCount)
意味着您的 form 表单所有要上传文件的 name
属性均是一样,maxCount
指定上传文件的最大数量,超过最大数量将报错 MulterError: Unexpected field。
<form action="/doPost" method="post" enctype="multipart/form-data">
<input type="text" name="name" id="name" />
<br/>
<input type="file" name="pic" id="pic" />
<br/>
<input type="file" name="pic" id="pic2" />
<br/>
<input type="file" name="pic" id="pic3" />
<br/>
<button type="submit">提交</button>
</form>
fields
upload.fields([{name: 'name',maxCount:NUMBER},...])
,它的参数形如:
[
{ name: 'pic', maxCount: 1 },
{ name: 'pic2', maxCount: 2 },
]
每一个 name 对应一个文件数组,此时,您的 form 表单就像下面那样编写
<form action="/doPost" method="post" enctype="multipart/form-data">
<input type="text" name="name" id="name" />
<br/>
<input type="file" name="pic" id="pic" />
<br/>
<input type="file" name="pic2" id="pic2" />
<br/>
<input type="file" name="pic2" id="pic3" />
<br/>
<button type="submit">提交</button>
</form>
参考:
https://www.npmjs.com/package/multer
https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md
https://www.jb51.net/article/95488.htm