You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Multer与Express Validator时req.files和req.body未定义问题

问题根源与修复方案

你的代码核心问题是重复执行了Multer的文件上传处理逻辑,导致请求体数据流被二次消费,最终req.files和req.body变为undefined。

具体问题点

路由定义中已经将uploadDocs作为中间件挂载:

router.post('/addDOoc', uploadDocs, docSizeErrhandler, checkSchema(data), (req, res) => { ... })

但在路由回调函数内部,你又再次调用了uploadDocs(req, res, function (err) { ... })。Multer处理文件上传时会读取multipart/form-data格式的请求数据流,这个流只能被消费一次,第二次调用时数据流已经耗尽,自然无法获取到文件和表单数据。

修复后的完整代码

/*schema for validation*/
var data = {
  'first_name': {
    notEmpty: true,
    errorMessage: "first name is required",
    isAlpha: true,
    errorMessage: 'first name must contain only alphabates',
    trim: true,
    escape: true
  },
  'last_name': {
    notEmpty: true,
    errorMessage: "last name is required",
    isAlpha: true,
    errorMessage: 'last name must contain only alphabates',
    trim: true,
    escape: true
  },
  'address': {
    notEmpty: true,
    errorMessage: "address is required",
  },
  'email': {
    notEmpty: true,
    errorMessage: "email id is required",
    isEmail: true,
    errorMessage: 'Enter Valid email',
    normalizeEmail: true,
    trim: true,
    escape: true
  },
  'mbl_num': {
    notEmpty: true,
    errorMessage: "mobile number is required",
    isInt: true,
    errorMessage: 'mobile number must contain only numbers',
  }
}
var maxSize = 3 * 1000 * 1000;//3mb
var DIR = './uploads/new/'; //uploads user documents folder
let docstorage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, DIR);
  },
  filename: (req, file, cb) => {
    cb(null, file.fieldname + '-' + Date.now() + '.pdf');
  }
});

/*upload function*/
var uploadDocs = multer({
  storage: docstorage,
  limits: { fileSize: maxSize },
  fileFilter: function (req, file, cb) {
    let file_name = file.originalname;
    let file_ext = file_name.split('.')[1];
    if (file.mimetype == 'application/pdf' && file_ext == 'pdf') {
      cb(null, true)
    } else {
      req.fileTypeInvalid = 'only pdf are allowed';
      cb(new Error('Invalid file type'));
    }
  }
}).array('files', 12)

// 统一处理Multer上传错误
const handleUploadErrors = (err, req, res, next) => {
  if (err) {
    if (req.fileTypeInvalid) {
      return res.status(406).send({ errMsg: req.fileTypeInvalid });
    }
    if (err.code === 'LIMIT_FILE_SIZE') {
      return res.status(406).send({ Apimessage: 'File size exceeds 3MB limit' });
    }
    return res.status(406).send({ Apimessage: 'Select Valid File' });
  }
  next();
}

router.post('/addDOoc', uploadDocs, handleUploadErrors, checkSchema(data), (req, res) => {
  // 直接获取验证结果,无需重复调用uploadDocs
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    console.log('validation errors:', errors);
    return res.status(400).send({
      code: 1,
      msg: 'Incorrect Data'
    });
  }

  // 此时req.files和req.body已正常填充
  console.log('req files--', req.files);
  console.log('bodyData', req.body);
  
  // 后续业务逻辑写在这里
  res.status(200).send({ msg: 'Data submitted successfully' });
});

关键修复说明

  1. 移除重复的uploadDocs调用:路由中间件已经完成文件上传处理,回调内无需再次执行
  2. 统一错误处理:将文件上传的错误处理整合到单独的中间件handleUploadErrors中,逻辑更清晰
  3. 保留正确的中间件顺序:文件上传(uploadDocs) → 上传错误处理 → 表单校验(checkSchema),确保校验时能获取到完整的表单和文件数据

内容的提问来源于stack exchange,提问作者sangRam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:35:23