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

使用multer上传文件时req.body为空、req.files为undefined如何解决

Multer单文件上传时req.body为空、req.files为undefined问题修复

核心问题根因

一共三个直接触发问题的错误,另有两个潜在bug:

  • 请求方法使用错误:文件上传携带FormData时使用了GET请求,HTTP规范中GET请求不支持携带请求体,浏览器、Node服务端默认会丢弃GET请求的body内容,这是数据接收不到的最核心原因。你项目里其他正常运行的多文件上传接口,必然是使用POST/PUT等支持请求体的方法,所以可以正常解析。
  • 单文件上传取值逻辑错误:使用multer.single('photo')配置单文件上传时,解析出的文件会挂载在req.file属性上,req.files仅在使用multer.array()/multer.fields()做多文件上传时才会赋值,直接访问req.files['photo']会因为req.files为undefined报错。
  • 文件名生成逻辑存在覆盖风险:随机数生成逻辑写在路由初始化外层,服务启动后仅会生成一次随机值,后续所有上传文件共用同一个前缀,仅靠时间戳区分文件名,高并发场景下同毫秒上传的文件会出现重名覆盖。
  • SQL返回逻辑错误:UPDATE语句执行后返回的是操作统计对象,不是用户数据列表,原代码直接遍历返回结果拿用户信息的逻辑永远不会触发。
  • 注意:axios发送FormData时不需要手动设置Content-Type: multipart/form-data请求头,手动设置会导致缺失自动生成的boundary分隔符,反而会让multer解析失败。

分步修复方案

1. 修正前后端请求方法

后端路由把GET改为POST:

// 原代码 router.get('/upload-photo', upload, (req, res) => {
router.post('/upload-photo', upload, (req, res) => {
  // 路由逻辑
})

前端axios请求把get改为post:

axios
  // 原代码 .get(`/api/user/upload-photo`, photoData)
  .post(`/api/user/upload-photo`, photoData)
  .then((res) => {
    dispatch(getPhotos());
  })
  // 后续catch逻辑保持不变

2. 修正单文件取值逻辑

路由内的文件取值从req.files改为req.file:

const id = req.body.id;
// 原代码 const photo = req.files['photo'][0].filename;
const photo = req.file.filename;

3. 修复文件名重名风险

把随机数生成逻辑移到filename回调内部,保证每次上传都生成新的随机前缀:

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, './client/public/images');
  },
  filename: function (req, file, cb) {
    // 每次上传重新生成随机数
    const random = Math.floor(Math.random() * 100000) + 10000;
    cb(null, random.toString() + new Date().getTime() + '.jpg');
  },
});

4. 修正UPDATE语句的返回逻辑

UPDATE执行后通过affectedRows判断是否更新成功,成功后重新查询对应用户信息返回:

db.query(
  'UPDATE users SET photo = ? WHERE id = ?',
  [photo, id],
  function (err, result) {
    if (err) throw err;
    if (result.affectedRows >= 1) {
      // 更新成功后查询对应用户信息
      db.query('SELECT id, photo FROM users WHERE id = ?', [id], function (queryErr, userRows) {
        if (queryErr) throw queryErr;
        res.json(userRows[0]);
      })
    } else {
      return res.status(200).json({});
    }
  }
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:42:20