介绍
之所以要单独说下文件上传,是因为body-parser
中间件不支持文件类型获取。我们平时都是用这个中间件去获取post数据,但是如果post过来的是一个文件,那它就不管用了。所以,我们需要新的中间件,那就是multer
。
multer
Multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件。
关于它的用法,可以参考文档:multer
注意:Multer 不会处理任何非 multipart/form-data 类型的表单数据。
什么是 multipart/form-data类型?
表单标签form上有一个enctype属性,它有三种值:
- application/x-www-form-urlencoded:在发送前编码所有字符(默认)
- multipart/form-data:不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。
- text/plain:空格转换为 “+” 加号,但不对特殊字符编码。
上传一个文件
现在就来实现一个文件上传。在这之前,确保你已经安装了express
和multer
。
app.js1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22const express = require('express')
const app = express()
//引入multer
const multer = require('multer')
//注册一个对象,dest里放的是上传的文件存储的位置,可以在当前目录下,建立一个static目录,上传的文件都放在这里
const upload = multer({dest: './static/'})
//使用中间件,没有挂载路径,应用的每个请求都会执行该中间件。any表示接受一切,具体参考文档。
app.use(upload.any())
//在req.files中获取文件数据
app.post('/',function(req, res){
console.log(req.files)
res.send('上传成功')
})
app.listen(3000)
现在准备一个表单1
2
3
4
5
6
7
8
9
10
11
12
13
14<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="http://localhost:3000/" method="post" enctype="multipart/form-data">
选择文件:
<input type="file" name="file1"><br>
<input type="submit" value="上传">
</form>
</body>
</html>
注意:在form里的enctype属性上必须填”multipart/form-data”。
现在执行app.js文件1
node app.js
在浏览器打开表单html文件,并上传一个文件,我上传了一张图片,然后在命令行里可以看到打印的数据,比如我的是:1
2
3
4
5
6
7
8[ { fieldname: 'file1',
originalname: 'html5.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: './static/',
filename: '2047b375bfaa68f984af6ac19e8df455',
path: 'static\\2047b375bfaa68f984af6ac19e8df455',
size: 9029 } ]
可以看到req.files是一个数组,因为可能不止传一个文件,每个文件的信息也很清晰就不多介绍了。
需要注意的是filename
这个属性,它就是上传后的文件名,可以到static目录里去看,它就是这样一个文件名且没有后缀,我们现在打不开它的,如果加上后缀,就可以打开了。我的图片是jpg格式,我在文件名后面加上.jpg
就可以正常打开了。
手动添加后缀名太麻烦了,既然用了node,那我们何不进一步处理,直接拿到有后缀名的文件呢?
优化
其实思路很简单,看打印出的文件信息,我们可以从originalname
里拿到文件后缀名,又可以在path
里拿到文件路径。好了,要做的无非就是拿到后缀名再重命名嘛。使用node中的path
和fs
模块,很容易实现。
1 | const express = require('express') |