Multer fileFilter 回调不抛出错误



我有这个fileffilter代码为multer。我的问题是,当我回调错误时,我的Express应用程序卡住了,最终页面给出ERR_CONNECTION_RESET。如果我尝试上传jpeg以外的文件,就会发生这种情况。

const upload = multer({
storage: storage,
fileFilter: function (req, file, cb) {
return cb(new ExpressError("Only images are allowed", 400));
},
});

存储是一个云存储,看起来像这样

const { CloudinaryStorage } = require("multer-storage-cloudinary");
const storage = new CloudinaryStorage({
cloudinary,
params: {
folder: "BilbaoBarrios",
allowedFormats: ["jpeg", "png", "jpg"],
},
});

另外,奇怪的是,如果我把存储变量放在FileFilter之后,它也可以处理png文件,但仍然不能处理任何其他文件格式,这意味着顺序在这里起作用。

感谢您的宝贵时间。

只是确认一下,cloudary是在办公室平台内并且在防火墙(或VPN)后面访问的吗?如果你是在防火墙后访问它,提供图像&其他cloudary.com有时需要在防火墙上将cloudary.com域名列入白名单。

另外,您可以查看我在这个链接上的示例,看看它是否也被阻止了:https://codesandbox.io/s/upload-feature-demo-ckvgi?file=/src/CldUploaderForm.js

在我的例子中,我包装了一次multer并将其用作中间件。

中间件/multer.js

const ErrorHandler = require("./error-handler");
const path = require("path");
const multer = require("multer");
function validator(types) {
const arr = [];
for (let type of types) {
switch (type) {
case "IMAGE":
arr.push("jpg", "jpeg", "png");
break;
case "PDF":
arr.push("pdf");
break;
case "EXCEL":
arr.push("excel", "vnd.openxmlformats-officedocument.spreadsheetml.sheet");
break;
}
}
regex = new RegExp(arr.join("|"), "gi");
return { regex, extensions: arr };
}
/**
* @param {String} form upload form ex) single|array|fields
* @param {String|Object[]} field fieldname of upload file
*      ex) single = 'image'
*      ex) array = ['image', 5]
*      ex) fields = [{name: 'image'}, {name: 'msds', maxCount: 1}]
* @param {String[]} condition field's extension type condition [fieldname: "image", extensionTypes: ["IMAGE"]]
*/
module.exports = ({ form, field, condition }) => {
return function (req, res, next) {
let allowExtensions;
const upload = multer({
dest: "uploads/",
fileFilter: function (req, file, cb) {
const [regCondition] = condition.filter((v) => v.fieldname == file.fieldname);
if (!regCondition) {
return cb("UNDEFINED_EXTENSTION_TYPE", false);
}
const { regex, extensions } = validator(regCondition.extensionTypes);
allowExtensions = extensions;
const extname = regex.test(path.extname(file.originalname));
const mimetype = regex.test(file.mimetype);
if (extname && mimetype) {
return cb(null, true);
} else {
return cb("EXTENSION_TYPE_ERROR", false);
}
},
});
let uploader;
switch (form) {
case "single":
uploader = upload.single(field);
break;
case "array":
uploader = upload.array(field[0], field[1]);
break;
case "fields":
uploader = upload.fields(field);
break;
}
uploader(req, res, (err) => {
if (err) {
if (err == "EXTENSION_TYPE_ERROR") {
e = new ErrorHandler(412, 5252, `Not allow file extension. Only files with the following extensions can be uploaded. [${allowExtensions.join(", ")}]`);
} else {
console.log(` >> Undefined multer error. ${err}`);
e = new ErrorHandler(500, 5252, "Internal Server Error");
}
e.handle(req, res);
} else {
next();
}
});
};
};
中间件/error-handler.js

const query = require("mysql2/promise");
const colors = require("colors/safe");
class ErrorHandler {
constructor(statusCode, errorCode, msg, Error) {
this.statusCode = statusCode ?? 500;
this.errorCode = errorCode ?? 9999;
this.msg = msg ?? "Undefined Error";
}
async handle(req, res, option) {
try {
const [error] = await query("SELECT * FROM error WHERE id = ?", [this.errorCode]);
if (error) {
this.msg = error.message ? error.message : this.msg;
}
} catch (e) {
this.errorCode = 5999;
this.msg = "An unexpected error occurred during error handling";
} finally {
console.log(`!! Error Occur ${colors.red(this.errorCode)} - ${new Date().toLocaleString()}`);
console.log(`Message : ${colors.green(this.msg)}`);
console.log(`URL : ${req.method} ${colors.bold(req.originalUrl)}`);
console.log(`UserId : ${colors.green(req.auth?.id)}`);
console.log("Request : ");
if (req.method === "GET" || req.method === "DELETE") {
console.log(req.query);
} else {
console.log(req.body);
}
res.status(this.errorCode).json({msg: this.msg});
}
}
}
module.exports = ErrorHandler;

路线/index.js

const express = require("express");
const asyncify = require("express-asyncify");
const router = asyncify(express.Router());
const multer = require("@/middlewares/multer");
router.post("/single", multer({ form: "single", field: "image", condition: [{ fieldname: "image", extensionTypes: ["IMAGE"] }] }), async (req, res) => {
const image = req.file;
// Do it your service
res.success(201);
});
router.post("/fields", multer({
form: "fields",
field: [
{ name: "images", maxCount: 10 },
{ name: "files", maxCount: 10 },
],
condition: [
{ fieldname: "images", extensionTypes: ["IMAGE"] },
{ fieldname: "files", extensionTypes: ["IMAGE", "PDF"] },
],
}), async (req, res) => {
const { images, files } = req?.files ?? {};
// Do it your service
res.success(201);
});
module.exports = router;

相关内容

最新更新