Multer教程:基于Nodejs的文件上传
一、multer介绍
multer是一个用来处理表单信息的nodejs中间件,主要是用于上传文件。multer基于busboy,拥有着更高的效率。
使用multer,你需要为form表单加上字段属性:enctype="multipart/form-data"
,这是因为multer不会处理除了 multipart/form-data 形式的表单信息。
二、安装multer
npm install --save multer
三、使用multer
multer会在 request
对象身上增加了 body
对象和 file
/ files
对象。其中,body 对象包含了文本字段形式的请求参数,而 file / files 则是上传的文件。
基本用法示例:
<form action="/profile" method="post" enctype="multipart/form-data">
<input type="file" name="avatar" />
<input type="text" name="nickname" />
</form>
const express = require('express');
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
const app = express();
app.post('/profile', upload.single('avatar'), (req, res, next) => {
// req.file 就是你上传的名为 avatar 的文件对象
// req.body 则包含文本字段形式的请求参数如 nickname
});
app.post('/profile', upload.array('avatar', 12), (req, res, next) => {
// req.files 包含多个名为 avatar 的文件对象的数组
// req.body 则包含文本字段形式的请求参数如 nickname
});
app.post('/profile', upload.fields([
{ name: 'avatar', maxCount: 1 },
{ name: 'gallery', maxCount: 8 }
]), (req, res, next) => {
// res.files => {
// avatar: [], -> 包含多个名为 avatar 的文件对象的数组
// gallery: [] -> 包含多个名为 gallery 的文件对象的数组
// }
// req.body 则包含文本字段形式的请求参数如 nickname
});
如果你上传的表单中只包含文本字段形式的请求参数,不包含文件,则你可以使用 .none()
方法:
app.post('/profile', upload.none(), (req, res, next) => {
// req.body 则包含文本字段形式的请求参数如 nickname
});
四、API参考
属性:
- File
方法:
- multer
- diskStorage
- memoryStorage
- fileFilter
- destination
- filename
对象:
- multerInstance
- multerOptions
- Limits
- StorageEngine
- DiskStorageOptions
4.1 multer
Multer multer(opts:Options);
说明:
创建 Instance
对象。
返回值:
Instance:instance对象。
示例:
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
4.2 Options
multer.Options
interface multerOptions {
String dest;
Limits limits;
Boolean preservePath;
StrorageEngine storage;
function void fileFilter() {};
}
说明:
用作 multer
方法的参数。一个最基本的 Options 应该含有一个 dest
字段,用于告诉 multer 你需要将上传的文件放置在哪一个文件夹下面。值得提醒的是,如果你忽略了这个属性,那么multer会将上传的文件暂存在内存中,而不会将其写入磁盘。
属性:
- limits:配置一些限制参数。
- dest:将文件保存在哪个目录下。
- storage:存储引擎,和 dest 一样的作用,两者配置一个即可,不同的地方将在下文提及。
- preservePath:是否保留文件的完整路径,而不仅仅是基本名称。
方法:
- fileFilter:控制哪些文件需要上传以及哪些文件可以忽略。
4.3 Limits
multer.Options.Limits
interface Limits {
Number fieldNameSize;
Number fieldSize;
Number fields;
Number fileSize;
Number files;
Number parts;
Number headerPairs;
}
说明:
配置了文件上传相关的一些大小限制。配置限制参数,有助于保护你的站点免受DoS攻击。multer 将这个对象直接传递给 busboy,更详细的属性可以前往 busboy 进行查看。
属性:
- fieldNameSize:字段名的最大长度,默认为 100 bytes。
- fieldSize:字段值的最大长度,默认为 1 MB。
- fields:非文件字段的最大数量,默认为 Infinity。
- fileSize:对于多字段表单,最大的文件大小(单位:bytes),默认为 Infinity。
- files:对于多字段表单,文件字段的最大数量,默认为 Infinity。
- parts:对于多字段表单,全部字段的最大数量,默认为 Infinity。
- headerPairs:对于多字段表单,解析的键值对最大数量,默认为 2000。
4.4 StorageEngine
multer.StorageEngine
构造:
- DiskStorage
- MemoryStorage
4.4.1 DiskStorage
磁盘存储引擎
StorageEngine multer.diskStorage(opts:DiskStorageOptions);
说明:
磁盘存储引擎为你提供了可以将文件保存到磁盘的完全控制权限。
返回值:
StorageEngine:存储引擎。
示例:
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 })
4.4.2 MemoryStorage
内存存储引擎
StorageEnigine multer.memoryStorage();
说明:
内存存储引擎将文件作为缓存对象存储在内存中,它没有任何可配置的选项。使用内存存储引擎时,文件信息将包含一个名为 buffer
的字段,该字段包含了整个文件。需要提醒的是,当你使用内存存储引擎时,若上传非常大的文件或相对较小的大量文件时,将会导致应用程序内存不足。
返回值:
StorageEngine:存储引擎。
4.5 fileFilter
void fileFilter(
req:Express.Request,
file:Multer.File,
callback:fileFilterCallback
);
说明:
控制哪些文件可以上传,哪些文件选择忽略。在该函数内,你需要调用 callback
函数,并传入一个 Boolean
类型的参数,以告知 multer 应该接受或丢弃该文件。
参数:
- req:http请求对象
- file:文件信息
- callback:回调函数
示例:
const upload = multer({
dest: 'uploads/',
fileFilter: function (req, file, cb) {
// 丢弃文件
cb(null, false);
// 接受文件
cb(null, true);
// 或者传递一个报错信息
cb(new Error('报错信息'));
}
});
4.6 DiskStorageOptions
interface DiskStorageOptions {
function void destination();
function void filename();
}
说明:
该对象拥有两个可配置的属性:destination
和 filename
。这两个属性将决定文件应该被存储在哪里。每个函数被调用时,都将被传入一个 req
参数 和 一个 file
参数,以帮助你做出决策。需要提醒的是,此时 req 的 body
对象可能尚未完全填充,这取决于客户端向服务器传输字段和文件的顺序。
属性:
- destination:文件存储目录
- filename:文件名
4.6.1 destination
void destination(
req:Express.Request,
file:Multer.File,
callback:destinationCallback
);
说明:
用于确定上传的文件应该被存储在哪个文件夹下。你需要调用 callback
函数,并传入一个 String
类型的参数,以告知 multer 应该将上传的文件存储在哪个文件夹下。特殊的:你也可以将该属性设置为 String
类型,它将直接表示文件夹的路径。如果你没有给出文件夹路径,那么上传的文件将会被存储在操作系统的临时文件默认目录。
注意:当该属性为 Sting 类型时,multer 将确保为你创建目录;当该属性为 Function 时,则需要你事先创建好目录。
示例:
const storage = multer.diskStorage({
destination: '/tmp/my-uploads'
});
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/tmp/my-uploads');
}
});
4.6.2 filename
void filename(
req:Express.Request,
file:Multer.File,
callback:filenameCallback
);
说明:
用于确定文件夹中文件的名称,你需要调用 callback
函数,并传入一个 String
类型的参数,已告知 multer 将上传的文件命名为你需要的名称。如果你没有给出文件名,那么为了保证命名不重复,上传的每个文件,都将被命名为一个不包含文件扩展名的随机名称。
注意:multer 不会为上传的文件自动添加文件扩展名,所以你传入的文件名参数中,一定要自己加上文件扩展名!
示例:
const storage = multer.diskStorage({
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now());
}
});
4.7 File
multer.File
interface File {
String fieldname;
String originalname;
String encoding;
String mimetype;
Number size;
String destination;
String filename;
String path;
Buffer buffer;
}
说明:
文件信息对象。
属性:
- fieldname:表单中指定的字段名。
- originalname:用户计算机上的文件名。
- encoding:文件的编码类型。
- mimetype:文件的mime类型。
- size:文件大小。
- destination:文件保存到的文件夹,使用DiskStorage时携带该属性。
- filename:文件的名称,使用DiskStorage时携带该属性。
- path:上传文件的完整路径,使用DiskStorage时携带该属性。
- buffer:整个文件的缓存区,使用MemoryStorage时携带该属性。
4.8 Instance
multer.Instance
构造:
multer({ dest: 'uploads/' });
方法:
- single(fieldname):接受一个指定字段名的文件,文件信息将携带在
req
对象的file
属性中。 - array(fieldname[, maxCount]):接受一个指定字段名的文件数组,如果上传的文件数量超过 maxCount 则可能会报错。文件信息将以数组的形式携带在
req
的files
属性中。 - fields(fields):接受由字段指定的混合文件。具有文件数组的对象在存储在
req.files
中。 - none():仅接受文本字段形式的请求参数。如果上传了文件,将发出代码为
LIMIT_UNEXPECTED_FILE
的错误。 - any():接受所有通过游戏传送的文件。文件数组将存储在请求文件中。
注意:切勿将 multer 添加文全局中间件,一些怀有恶意的用户可能会将文件上传到你没有预料到的路径。确保仅在处理上传文件的路由上使用此功能。
以上便是有关 multer 的所有内容,希望对正在寻找这方面教程的你有所帮助。更详细的内容请前往 multer 查看。