对于multer的了解可以在 https://www.npmjs.com/ 搜索 multer 了解具体用法。
Multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件。它是写在 busboy 之上非常高效。
注意: Multer 不会处理任何非 multipart/form-data 类型的表单数据。
同时需要知道 Multer 会添加一个 body 对象 以及 file 或 files 对象 到 express 的 request 对象中。 body 对象包含表单的文本域信息,file 或 files 对象包含对象表单上传的文件信息。
在项目终端中,直接输入命令
$ npm install --save multer
为了更好的了解multer是如何工作的,我们先了解一下官网定义的multer的基本使用规则。
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 是 `avatar` 文件的信息
// req.body 将具有文本域数据,如果存在的话
})
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// req.files 是 `photos` 文件数组的信息
// req.body 将具有文本域数据,如果存在的话
})
下面笔者对一些知识点进行简单的解读。
1.const upload = multer({ dest: ‘uploads/’ })
dest是一个最基本的属性,其告诉multer将上传的文件保存在哪。
如上述代码,multer将会把上传的文件存储在uploads的目录下面,前提是需要有uploads目录。
2.upload.single(‘avatar’)
指的是multer将会上传表单数据中key为avatar的数据,且存放在定义好的文件目录中。
3.upload.array(‘photos’, 12)
指的是multer将会上传表单数据中key为photos的多个文件数据,且存放在定义好的文件目录中。
下面是官网的具体解读。
multer(opts)
Multer 接受一个 options 对象,其中最基本的是 dest 属性,这将告诉 Multer 将上传文件保存在哪。如果你省略 options 对象,这些文件将保存在内存中,永远不会写入磁盘。
以下是可以传递给 Multer 的选项。
| Key | Description |
| dest or storage | 在哪里存储文件 |
| fileFilter | 文件过滤器,控制哪些文件可以被接受 |
| limits | 限制上传的数据 |
| preservePath | 保存包含文件名的完整文件路径 |
.single(fieldname)
接受一个以 fieldname 命名的文件。这个文件的信息保存在 req.file。
.array(fieldname[, maxCount])
接受一个以 fieldname 命名的文件数组。可以配置 maxCount 来限制上传的最大数量。这些文件的信息保存在 req.files。
经过对multer的简单了解之后,下面笔者展示具体的实现代码(上传单个文件)。
//创建multer实例对象,通过dest属性指定文件存放路径
const express= require('express'); //导入express模块
const router = express.Router(); //创建路由对象
//导入multer模块,解析formdata格式表单数据报
const multer = require('multer');
//导入处理路径的核心模块
const path = require('path');
//存储到uploads目录所在的绝对路径上。
const upload = multer({ dest: path.join(__dirname, '../uploads') })
//发布新文章的路由
router.post('/add',upload.single('cover_img'),articleHandler.addArticle)
router_handler\article.js
exports.addArticle = (req, res) => {
// 手动判断是否上传了文章封面
if (!req.file || req.file.fieldname !== "cover_img")
return res.msg("文章封面是必选参数!");//res.msg是封装返回结果的函数
// TODO:表单数据合法,继续后面的数据处理流程...
//...这里可以把数据填充到数据库中...
// 发布文章成功
res.msg("发布文章成功", 0);
});
};
至此,文件上传就实现完毕。下面利用ApiPost来测试接口是否正确。
在这里笔者测试的时候选择一张图片以及附带各类数据信息。
注意,传送的表单数据格式一定是要formData格式。
下面是服务响应结果。
接着在uploads目录中检查是否有该文件。(multer上传文件不会保留文件拓展名)
最后通过浏览器打开文件验证是否能正常看到图片。
//下载的路由
router.get('/download', articleHandler.downloadArticle)
exports.downloadArticle = (req, res) => {
const filePath = path.join(
__dirname,
"../uploads",
"/fcc2ccb87aabeefbe3f72ecae98b97fa"
);
fs.readFile(filePath, (isErr, data) => {
if (isErr) {
console.log(isErr.message);
res.end("Read file failed!");
return;
}
res.writeHead(200, {
"Content-Type": "application/octet-stream", //告诉浏览器这是一个二进制文件
"Content-Disposition": "attachment; filename=" + encodeURI("test下载文件.png"), //告诉浏览器这是一个需要下载的文件
});
res.end(data);
});
};
这里笔者为了方便直接输入常量值文件名,但是一般我们的数据是存储在数据库的,我们可以通过查询数据库信息,把对应的文件信息取出,把所有的常量值改为变量即可。要注意,要使用encodeURI对含有中文路径的文件进行编码。
直接使用 location.href = ‘http://localhost:8080/my/article/download’ 进行访问即可。(前提是先设置好跨域)
对于下载实现来说,我们只需要确保数据库存储的文件路径正确,保证文件存在,文件拓展名正确,就可以实现任意类型的文件下载。包括rar压缩文件。
对于上传实现来说,我们需要保证存放目录是否存在,以及限制好文件类型,文件最大运行的大小即可。同时要保证是以formData数据格式进行传输。