正文
什么是Multer?
Multer是一个Node.js中间件,用于处理 multipart/form-data类型的表单数据,它主要用于上传文件。它是写在busboy之上非常高效。
注意: Multer不会处理任何非multipart/form-data类型的表单数据。
如何安装?
代码语言:javascript复制$ npm install --save multer
怎么使用?
Multer 会添加一个body对象以及file或files对象到express的request对象中。 body对象包含表单的文本域信息,file或files对象包含对象表单上传的文件信息。
基本使用方法:
代码语言:javascript复制const express = require('express')
const multer = require('multer')
const upload = multer({ dest: 'uploads/' })
const app = express()
app.post('/upload', upload.single('file'), function (req, res, next) {
// req.file 是file文件的信息
// req.body 将具有文本域数据,如果存在的话
})
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// req.files 是photos文件数组的信息
// req.body 将具有文本域数据,如果存在的话
})
const cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
app.post('/cool-profile', cpUpload, function (req, res, next) {
// req.files 是一个对象 (String -> Array) 键是文件名,值是文件数组
//
// 例如:
// req.files['avatar'][0] -> File
// req.files['gallery'] -> Array
//
// req.body 将具有文本域数据,如果存在的话
})
Multer API
Key | Description | Note |
---|---|---|
fieldname | Field name 由表单指定 | |
originalname | 用户计算机上的文件的名称 | |
encoding | 文件编码 | |
mimetype | 文件的 MIME 类型 | |
size | 文件大小(字节单位) | |
destination | 保存路径 | DiskStorage |
filename | 保存在destination中的文件名 | DiskStorage |
path | 已上传文件的完整路径 | DiskStorage |
buffer | 一个存放了整个文件的Buffer | MemoryStorage |
Multer(opts) 参数
Multer 接受一个options对象,其中最基本的是dest属性,这将告诉Multer将上传文件保存在哪。如果你省略options对象,这些文件将保存在内存中,永远不会写入磁盘。
为了避免命名冲突,Multer 会修改上传的文件名。这个重命名功能可以根据您的需要定制。
以下是可以传递给 Multer 的选项。
Key | Description |
---|---|
dest or storage | 在哪里存储文件 |
fileFilter | 文件过滤器,控制哪些文件可以被接受 |
limits | 限制上传的数据 |
preservePath | 保存包含文件名的完整文件路径 |
通常,一般的网页应用,只需要设置dest属性,像这样:
代码语言:javascript复制const upload = multer({ dest: 'uploads/' })
如果你想在上传时进行更多的控制,你可以使用storage选项替代dest。Multer具有DiskStorage和MemoryStorage两个存储引擎;另外还可以从第三方获得更多可用的引擎。
Multer对象方法
single(fieldname)
接受一个以fieldname命名的文件。这个文件的信息保存在req.file。
array(fieldname[, maxCount])
接受一个以fieldname命名的文件数组。可以配置maxCount来限制上传的最大数量。这些文件的信息保存在req.files。
fields(fields)
接受指定fields的混合文件。这些文件的信息保存在req.files。 fields应该是一个对象数组,应该具有name和可选的maxCount属性。
none()
只接受文本域。如果任何文件上传到这个模式,将发生 "LIMIT_UNEXPECTED_FILE" 错误。这和upload.fields([])的效果一样。
any()
接受一切上传的文件。文件数组将保存在req.files。
警告: 确保你总是处理了用户的文件上传。 永远不要将 multer 作为全局中间件使用,因为恶意用户可以上传文件到一个你没有预料到的路由,应该只在你需要处理上传文件的路由上使用。
如何存放磁盘?
磁盘存储引擎 (DiskStorage)
磁盘存储引擎可以让你控制文件的存储。
代码语言:javascript复制const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/tmp/my-uploads')
},
filename: function (req, file, cb) {
cb(null, file.fieldname '-' Date.now())
}
})
const upload = multer({ storage: storage })
有两个选项可用,destination和filename。他们都是用来确定文件存储位置的函数。
destination是用来确定上传的文件应该存储在哪个文件夹中。也可以提供一个string(例如'/tmp/uploads')。如果没有设置destination,则使用操作系统默认的临时文件夹。
注意: 如果你提供的destination是一个函数,你需要负责创建文件夹。当提供一个字符串,Multer将确保这个文件夹是你创建的。 filename用于确定文件夹中的文件名的确定。如果没有设置filename,每个文件将设置为一个随机文件名,并且是没有扩展名的。
注意: Multer不会为你添加任何扩展名,你的程序应该返回一个完整的文件名。 每个函数都传递了请求对象 (req) 和一些关于这个文件的信息 (file),有助于你的决定。 注意: req.body可能还没有完全填充,这取决于向客户端发送字段和文件到服务器的顺序。
内存存储引擎 (MemoryStorage)
内存存储引擎将文件存储在内存中的Buffer对象,它没有任何选项。
代码语言:javascript复制const storage = multer.memoryStorage()
const upload = multer({ storage: storage })
当使用内存存储引擎,文件信息将包含一个buffer字段,里面包含了整个文件数据。
警告: 当你使用内存存储,上传非常大的文件,或者非常多的小文件,会导致你的应用程序内存溢出。
limits 大小限制
一个对象,指定一些数据大小的限制。Multer 通过这个对象使用 busboy。
可以使用下面这些:
Key | Description | Default |
---|---|---|
fieldNameSize | field 名字最大长度 | 100 bytes |
fieldSize | field 值的最大长度 | 1MB |
fields | 非文件 field 的最大数量 | 无限 |
fileSize | 在 multipart 表单中,文件最大长度 (字节单位) | 无限 |
files | 在 multipart 表单中,文件最大数量 | 无限 |
parts | 在 multipart 表单中,part 传输的最大数量(fields files) | 无限 |
headerPairs | 在 multipart 表单中,键值对最大组数 | 2000 |
设置 limits 可以帮助保护你的站点抵御拒绝服务 (DoS) 攻击。
fileFilter 文件过滤
设置一个函数来控制什么文件可以上传以及什么文件应该跳过,这个函数应该看起来像这样:
代码语言:javascript复制function fileFilter (req, file, cb) {
// 这个函数应该调用cb用boolean值来
// 指示是否应接受该文件
// 拒绝这个文件,使用false,像这样:
cb(null, false)
// 接受这个文件,使用true,像这样:
cb(null, true)
// 如果有问题,你可以这样发送一个错误:
cb(new Error('I don't have a clue!'))
}
结语
以上就是关于Multer的所有相关介绍以及使用方法,为了大家更好的理解以及使用Multer,下面给大家再分享一下我个人博客写的一个上传接口,以便大家更容易的使用它。这个接口本身是使用typescript写的,为了让大家更容易看明白,我为大家已经简化成普通js了,以下是相关代码。
代码语言:javascript复制import express from 'express';
import fs from 'fs';
import multer from 'multer';
import path from 'path';
let app = express(),
coverPath = path.resolve(__dirname, '../../assets/images/cover'),
//创建dir
createFolder = folder => {
try {
fs.accessSync(folder);
} catch (e) {
fs.mkdirSync(folder);
}
},
//设置文件后缀 & 存储路径
storage = path => multer.diskStorage({
//存储文件路径
destination: (req, file, cb) => {
cb(null, path);
},
//文件名称,默认不带后缀,补上后缀
filename: (req, file, cb) => {
let originalname = file.originalname;
cb(null, utils.MD5(Date.now().toString()) '_' originalname);
}
}),
//接口响应
release = ( req, res, err) => {
if (err || !req.file) {
return res.json({
success: false,
errorCode: '',
errorMsg: '文件上传失败',
data: err
});
}
res.json({
success: true,
errorCode: '',
errorMsg: '文件上传成功',
data: {
imgUrl: `//static.wujiabk.com/images/cover/${req.file.filename}` || ''
}
});
}
createFolder(coverPath) //保证存储目录的存在性,先创建目录
const uploadCover = multer({ storage: storage(coverPath) }).single('file')
app.post('/upload/cover', uploadCover, (req, res, next) => {
uploadCover(release);
});