当我在 multer 中使用文件过滤器时如何捕获错误?
How to catch the error when i am using file filter in multer?
我已经搜索过,但找不到确切的解决方案。当我上传图像时,它应该只允许 jpg、jpeg、gif、png。如果有任何其他文件,它应该在 UI 中显示消息。我使用了以下代码
var upload = multer({ storage: storage,
fileFilter: function (req, file, cb) {
var ext = path.extname(file.originalname);
if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
return cb(new Error('Wrong extension type'));
// if(Error){
// console.log("error file type")
// }
}
cb(null, true)
}
});
如果我尝试上传图片而不是 jpeg、jpg、png,git 它显示错误..但是如何在我的应用程序页面本身显示为消息
Error: Wrong extension type
at fileFilter (D:\Vishnu\octopus new\app\routes.js:912:24)
at wrappedFileFilter (D:\Vishnu\octopus new\node_modules\multer\index.js:44:7)
at Busboy.<anonymous> (D:\Vishnu\octopus new\node_modules\multer\lib\make-middleware.js:114:7)
at emitMany (events.js:127:13)
at Busboy.emit (events.js:201:7)
at Busboy.emit (D:\Vishnu\octopus new\node_modules\busboy\lib\main.js:38:33)
at PartStream.<anonymous> (D:\Vishnu\octopus new\node_modules\busboy\lib\types\multipart.js:213:13)
at emitOne (events.js:96:13)
at PartStream.emit (events.js:188:7)
at HeaderParser.<anonymous> (D:\Vishnu\octopus new\node_modules\dicer\lib\Dicer.js:51:16)
at emitOne (events.js:96:13)
at HeaderParser.emit (events.js:188:7)
at HeaderParser._finish (D:\Vishnu\octopus new\node_modules\dicer\lib\HeaderParser.js:68:8)
at SBMH.<anonymous> (D:\Vishnu\octopus new\node_modules\dicer\lib\HeaderParser.js:40:12)
at emitMany (events.js:127:13)
at SBMH.emit (events.js:201:7)
请帮助我解决这个问题.. 提前致谢
我也被这个问题困扰了一段时间。我以为我找到了一个解决方案,但它最终对我来说效果不佳,但经过足够的修补和今晚环顾四周,我找到了一个适合我的答案。我希望这有帮助。 我在四处寻找答案时发现了这个问题。
所以我所做的是在您的示例中创建 req.fileValidationError:
var upload = multer({
fileFilter: function (req, file, cb) {
let ext = path.extname(file.originalname);
if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
req.fileValidationError = "Forbidden extension";
return cb(null, false, req.fileValidationError);
}
cb(null, true);
}
});
然后在您的路线中您要使用 if 语句检查 req.fileValidationError。如果它存在,那么您就知道存在禁止扩展。
假设您在 app 变量下使用 express,并且您希望发送单个图像,它看起来像这样:
app.post('/your-upload-route', upload.single("your-input-name-here"), function(req, res) {
if (req.fileValidationError) {
// return res.sendFile();
// or return res.end();
// or even res.render(); whatever response you want here.
}
});
希望对您有所帮助!如果其他人有不同的方法,我很乐意更新我的答案并了解其他人的见解。
添加到这个答案中,顺便说一下,它就像一个魅力。
如果您想要全面解决因文件未被 MIME 类型接受或文件未附加而导致的错误,您可以执行以下操作:
将您的 FileFilter 函数设置为如下所示:
const upload = multer({
storage: //storage declaration here,
fileFilter: (req, file, cb) => {
if (
!file.mimetype.includes("image/png") &&
!file.mimetype.includes("image/jpeg")
) {
return cb(null, false);
}
cb(null, true);
}
});
然后在你的路线或任何你的 req
,res 范围内,你可以通过检查通常保存上传文件信息的 req.file
变量来捕获错误并做出相应的响应:
if (!req.file) {
console.log("No file received or invalid file type");
return res.status(400).send({
message: "No file received or invalid file type",
success: false
});
}
无需设置新的 req
变量来保存 ValidationError
,如果用户未提供有效文件,您可以优雅地响应他们。
这是有效的,因为 FileFilter 将成功过滤掉与您的验证不匹配的文件,即使没有在回调中抛出错误,但它不会抛出错误,只是不会继续接受文件。我不完全理解为什么 multer 中的回调是以这种方式构建的,因为抛出错误的方法不会冒泡到您的路由或控制器。
然而,使用上面的代码,如果 fileFilter 完成了它的工作,当您使用 if(!req.file){}
检查 req.file
是否存在(或在本例中不存在)时,您可以捕获两者- 文件提交和验证失败,没有从 fileFilter 的回调中抛出的混乱错误:)
fileFilter 回调应该是:
var upload = multer({
storage: storage,
fileFilter: function (req, file, cb) {
var ext = path.extname(file.originalname);
if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
cb(new Error('Wrong extension type'), false);
}
cb(null, true)
}
});
请求中的错误处理:
- 使用
MulterError
访问多个错误
const multer = require("multer");
router.post('/upload', function(req, res) {
upload.single('field name')(req, res, function(err) {
// FILE SIZE ERROR
if (err instanceof multer.MulterError) {
return res.end("Max file size 2MB allowed!");
}
// INVALID FILE TYPE, message will return from fileFilter callback
else if (err) {
return res.end(err.message);
}
// FILE NOT SELECTED
else if (!req.file) {
return res.end("File is required!");
}
// SUCCESS
else {
console.log("File uploaded successfully!");
console.log("File response", req.file);
}
)}
})
借助中间件处理异常的替代方法
router.post("/v1/user/create",uploadFile,customBadRequestException,customBadFileRequestException)
自定义异常
exports.customBadRequestException = (req,res,next) => {
if(!req.body || !req.body.data || !req.body.data.length || !req.file || !req.file.filename){
return res.status(400).send({ message: "Bad request" });
}
next();
};
exports.customBadFileRequestException = (req,res,next) => {
if (! /\.(jpe?g|png|gif|bmp)$/i.test(req.file.filename)) {
return res.status(400).send({ message: "Please upload only images" });
}
next();
};
多配置
const multer = require("multer");
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null,"/Users/path/Desktop/testFiles");
},
filename: (req, file, cb) => {
cb(null, `${Date.now()}-${file.originalname}`);
},
});
var uploadFile = multer({ storage: storage}).single("file");
module.exports = uploadFile;
我已经搜索过,但找不到确切的解决方案。当我上传图像时,它应该只允许 jpg、jpeg、gif、png。如果有任何其他文件,它应该在 UI 中显示消息。我使用了以下代码
var upload = multer({ storage: storage,
fileFilter: function (req, file, cb) {
var ext = path.extname(file.originalname);
if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
return cb(new Error('Wrong extension type'));
// if(Error){
// console.log("error file type")
// }
}
cb(null, true)
}
});
如果我尝试上传图片而不是 jpeg、jpg、png,git 它显示错误..但是如何在我的应用程序页面本身显示为消息
Error: Wrong extension type
at fileFilter (D:\Vishnu\octopus new\app\routes.js:912:24)
at wrappedFileFilter (D:\Vishnu\octopus new\node_modules\multer\index.js:44:7)
at Busboy.<anonymous> (D:\Vishnu\octopus new\node_modules\multer\lib\make-middleware.js:114:7)
at emitMany (events.js:127:13)
at Busboy.emit (events.js:201:7)
at Busboy.emit (D:\Vishnu\octopus new\node_modules\busboy\lib\main.js:38:33)
at PartStream.<anonymous> (D:\Vishnu\octopus new\node_modules\busboy\lib\types\multipart.js:213:13)
at emitOne (events.js:96:13)
at PartStream.emit (events.js:188:7)
at HeaderParser.<anonymous> (D:\Vishnu\octopus new\node_modules\dicer\lib\Dicer.js:51:16)
at emitOne (events.js:96:13)
at HeaderParser.emit (events.js:188:7)
at HeaderParser._finish (D:\Vishnu\octopus new\node_modules\dicer\lib\HeaderParser.js:68:8)
at SBMH.<anonymous> (D:\Vishnu\octopus new\node_modules\dicer\lib\HeaderParser.js:40:12)
at emitMany (events.js:127:13)
at SBMH.emit (events.js:201:7)
请帮助我解决这个问题.. 提前致谢
我也被这个问题困扰了一段时间。我以为我找到了一个解决方案,但它最终对我来说效果不佳,但经过足够的修补和今晚环顾四周,我找到了一个适合我的答案。我希望这有帮助。 我在四处寻找答案时发现了这个问题。
所以我所做的是在您的示例中创建 req.fileValidationError:
var upload = multer({
fileFilter: function (req, file, cb) {
let ext = path.extname(file.originalname);
if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
req.fileValidationError = "Forbidden extension";
return cb(null, false, req.fileValidationError);
}
cb(null, true);
}
});
然后在您的路线中您要使用 if 语句检查 req.fileValidationError。如果它存在,那么您就知道存在禁止扩展。
假设您在 app 变量下使用 express,并且您希望发送单个图像,它看起来像这样:
app.post('/your-upload-route', upload.single("your-input-name-here"), function(req, res) {
if (req.fileValidationError) {
// return res.sendFile();
// or return res.end();
// or even res.render(); whatever response you want here.
}
});
希望对您有所帮助!如果其他人有不同的方法,我很乐意更新我的答案并了解其他人的见解。
添加到这个答案中,顺便说一下,它就像一个魅力。
如果您想要全面解决因文件未被 MIME 类型接受或文件未附加而导致的错误,您可以执行以下操作:
将您的 FileFilter 函数设置为如下所示:
const upload = multer({
storage: //storage declaration here,
fileFilter: (req, file, cb) => {
if (
!file.mimetype.includes("image/png") &&
!file.mimetype.includes("image/jpeg")
) {
return cb(null, false);
}
cb(null, true);
}
});
然后在你的路线或任何你的 req
,res 范围内,你可以通过检查通常保存上传文件信息的 req.file
变量来捕获错误并做出相应的响应:
if (!req.file) {
console.log("No file received or invalid file type");
return res.status(400).send({
message: "No file received or invalid file type",
success: false
});
}
无需设置新的 req
变量来保存 ValidationError
,如果用户未提供有效文件,您可以优雅地响应他们。
这是有效的,因为 FileFilter 将成功过滤掉与您的验证不匹配的文件,即使没有在回调中抛出错误,但它不会抛出错误,只是不会继续接受文件。我不完全理解为什么 multer 中的回调是以这种方式构建的,因为抛出错误的方法不会冒泡到您的路由或控制器。
然而,使用上面的代码,如果 fileFilter 完成了它的工作,当您使用 if(!req.file){}
检查 req.file
是否存在(或在本例中不存在)时,您可以捕获两者- 文件提交和验证失败,没有从 fileFilter 的回调中抛出的混乱错误:)
fileFilter 回调应该是:
var upload = multer({
storage: storage,
fileFilter: function (req, file, cb) {
var ext = path.extname(file.originalname);
if(ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
cb(new Error('Wrong extension type'), false);
}
cb(null, true)
}
});
请求中的错误处理:
- 使用
MulterError
访问多个错误
const multer = require("multer");
router.post('/upload', function(req, res) {
upload.single('field name')(req, res, function(err) {
// FILE SIZE ERROR
if (err instanceof multer.MulterError) {
return res.end("Max file size 2MB allowed!");
}
// INVALID FILE TYPE, message will return from fileFilter callback
else if (err) {
return res.end(err.message);
}
// FILE NOT SELECTED
else if (!req.file) {
return res.end("File is required!");
}
// SUCCESS
else {
console.log("File uploaded successfully!");
console.log("File response", req.file);
}
)}
})
借助中间件处理异常的替代方法
router.post("/v1/user/create",uploadFile,customBadRequestException,customBadFileRequestException)
自定义异常
exports.customBadRequestException = (req,res,next) => {
if(!req.body || !req.body.data || !req.body.data.length || !req.file || !req.file.filename){
return res.status(400).send({ message: "Bad request" });
}
next();
};
exports.customBadFileRequestException = (req,res,next) => {
if (! /\.(jpe?g|png|gif|bmp)$/i.test(req.file.filename)) {
return res.status(400).send({ message: "Please upload only images" });
}
next();
};
多配置
const multer = require("multer");
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null,"/Users/path/Desktop/testFiles");
},
filename: (req, file, cb) => {
cb(null, `${Date.now()}-${file.originalname}`);
},
});
var uploadFile = multer({ storage: storage}).single("file");
module.exports = uploadFile;