You need to enable JavaScript to run this app. Multer.single方法无法将上传文件挂载到req对象的问题求助
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 03:39:04