在Node.js的Express项目开发中,文件上传是常见功能需求,Multer作为专门处理multipart/form-data格式数据的中间件,能够高效处理文件上传逻辑,同时支持对上传文件的大小、类型进行自定义验证,避免无效文件或超大文件上传到服务器。

Multer基础配置说明
Multer的核心配置分为两部分,一部分是全局的文件大小限制,另一部分是自定义的文件过滤函数,用于校验文件类型。首先需要通过npm安装Multer依赖:
npm install multer express
核心配置参数
- limits:用于设置上传文件的全局限制,其中fileSize字段可以指定单个文件的最大大小,单位是字节。
- fileFilter:是一个自定义函数,接收请求对象、上传的文件对象和回调函数三个参数,用于判断文件是否符合类型要求。
- storage:用于配置文件存储方式,这里以内存存储为例,实际项目可以根据需求调整为磁盘存储。
实现图片大小和类型验证
下面通过一个完整的Express接口示例,展示如何配置Multer实现图片大小和类型的双重验证。
完整的服务代码实现
const express = require('express');
const multer = require('multer');
const app = express();
// 配置内存存储,文件会暂存在内存中,不会写入磁盘
const storage = multer.memoryStorage();
// 允许上传的图片类型列表
const allowedImageTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
// 自定义文件过滤函数,校验文件类型
const fileFilter = (req, file, cb) => {
if (allowedImageTypes.includes(file.mimetype)) {
// 类型符合要求,允许上传
cb(null, true);
} else {
// 类型不符合要求,拒绝上传并传递错误信息
cb(new Error('不支持的图片类型,仅允许上传jpeg、png、gif、webp格式的图片'), false);
}
};
// 创建Multer实例,配置大小和类型验证规则
const upload = multer({
storage: storage,
// 限制单个文件最大为2MB,2*1024*1024=2097152字节
limits: {
fileSize: 2097152
},
fileFilter: fileFilter
});
// 图片上传接口,使用single方法处理单个文件上传,字段名为image
app.post('/upload/image', upload.single('image'), (req, res) => {
res.json({
code: 200,
message: '图片上传成功',
// 返回文件的基础信息
fileInfo: {
originalName: req.file.originalname,
size: req.file.size,
mimeType: req.file.mimetype
}
});
});
// 错误处理中间件,捕获Multer抛出的错误
app.use((err, req, res, next) => {
if (err instanceof multer.MulterError) {
// Multer自身的错误,比如文件大小超限
if (err.code === 'LIMIT_FILE_SIZE') {
return res.json({
code: 400,
message: '上传的图片大小不能超过2MB'
});
}
} else if (err) {
// 自定义抛出的错误,比如类型不符合要求
return res.json({
code: 400,
message: err.message
});
}
next();
});
app.listen(3000, () => {
console.log('服务运行在3000端口');
});
代码逻辑说明
上述代码中,首先定义了允许的图片MIME类型列表,在fileFilter函数中校验上传文件的mimetype是否在允许列表中,不符合则通过回调函数传递错误。同时在Multer的limits配置中设置fileSize为2MB,超过这个大小的请求会被Multer拦截。最后添加了错误处理中间件,统一捕获上传过程中的各类错误,返回友好的提示信息。
常见问题说明
在实际使用中需要注意,文件的mimetype是客户端传递的信息,部分场景下可能存在伪造的情况,如果需要更严格的校验,可以在文件上传后通过读取文件二进制头信息判断真实类型。另外如果上传的是多个图片文件,可以使用upload.array('images', 5)的方式,同时限制最多上传5个文件,大小限制会对每个文件单独生效。
如果需要在上传后把文件保存到指定目录,可以将存储方式改为磁盘存储,配置如下:
const storage = multer.diskStorage({
// 配置文件保存路径
destination: function (req, file, cb) {
cb(null, './uploads/');
},
// 配置文件保存的文件名
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
cb(null, uniqueSuffix + '-' + file.originalname);
}
});
修改存储配置后,其他验证逻辑不需要变动,依然可以正常生效,文件会保存到指定的uploads目录下,避免文件名冲突。