Multer.single方法无法将上传文件挂载到req对象的问题求助
问题排查与修复方案
1. 表单缺少文件上传必需的enctype属性
HTML表单上传二进制文件时,必须指定enctype="multipart/form-data",默认的编码格式不支持文件传输,所以Multer无法接收到上传的文件。
修正后的PUG表单代码:
form(action="/competitions",method="POST", enctype="multipart/form-data").flex input(type="text", name="name" placeholder="Competition name") span Competition logo div.flex img(src="https://via.placeholder.com/150", alt="")#comp-logo input(type="file" name="file")#comp-file-input input(type="submit", value="Create competition")
2. 文件存在性判断逻辑错误
Multer解析后的单文件资源存放在req.file对象中,不会出现在req.body里,你当前判断!req.body.file的逻辑永远会触发必填校验报错。
修正resizeAndSaveCompImages里的校验逻辑:
exports.resizeAndSaveCompImages = catchAsync(async (req, res, next) => { // 把req.body.file改成req.file if (!req.file) { return res .status(401) .redirect( "/user/adminpanel/competitionform?error=Each competition must have a logo" ); } // 后续原有逻辑保持不变 const competitionLogoFileName = `${Date.now()}-logo-${req.body.name.replace( " ", "-" )}.png`; await sharp(req.file.buffer) .toFormat("png") .resize(24, 24) .toFile(`static/images/competitions/${competitionLogoFileName}`); req.body.logo = competitionLogoFileName; next(); });
3. Multer文件过滤器的回调写法不规范
Multer的fileFilter回调第一个参数要求传入Error对象,不能直接传入res.redirect()的返回值,否则可能引发未捕获的异常。修正写法:
const multerFilter = (req, file, cb) => { if (file.mimetype.startsWith("image")) { cb(null, true); } else { // 先执行重定向逻辑,再给回调传参数 res .status(401) .redirect( "/user/adminpanel/competitionform?error=Competition logo must be an image" ); // 第二个参数传false拒绝该文件 cb(null, false); } };
以上三个问题全部修正后,即可正常完成赛事Logo的上传、处理和保存逻辑。
内容的提问来源于stack exchange,提问作者Farid Ghaderi
相关产品推荐
相关产品推荐

