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

使用fetch API发送FormData时req.body为空,返回500错误求助

问题描述

使用fetch API发送包含用户输入的FormData作为POST请求时,后端req.body为空对象;不使用form-data格式时请求正常,数据能存入req.body,请求返回500内部服务器错误。

前端代码

/*
some code ...
*/

const formData = new FormData();
formData.append('name', formState.inputs.name.value);
formData.append('email', formState.inputs.email.value);
formData.append('password', formState.inputs.password.value);
formData.append('image', formState.inputs.image.value);

const responseData = await fetch(
  "http://localhost:5000/api/users/signup",
  {
    method: "POST",
    body: formData
  }
);
// 返回 >>> POST http://localhost:5000/api/users/signup 500 (Internal Server Error)

后端代码

users-controllers.js

/*
some code ...
*/

const signup = (req, res, next) => {
  res.json({user: req.body})
}

module.exports = {
  getUsers,
  signup,
  login,
};

user-routes.js

const express = require("express");
const { body } = require("express-validator");

const { getUsers, signup, login } = require("../controllers/users-controllers");
const fileUpload = require('../middleware/file-upload');

const router = express.Router();

router.get("/", getUsers);

router.post(
  "/signup",
  fileUpload.single('image'),
  body("name").not().isEmpty(),
  body("email").normalizeEmail().isEmail(),
  body("password").isLength({ min: 6 }),
  signup
);

router.post("/login", login);

module.exports = router;

file-upload.js

const multer = require('multer');
const { v1: uuidv1 } = require('uuid');

const MIME_TYPE_MAP = {
    'image/png': 'png',
    'image/jpeg': 'jpeg',
    'image/jpg': 'jpg'
}

const fileUpload = multer({
    limits: 500000,
    storage: multer.diskStorage({
        destination: (req, file, cb) => {
            cb(null, 'uploads/images');
        },
        filename: (req, file, cb) =>  {
            const ext = MIME_TYPE_MAP[file.mimetype];
            cb(null, uuidv1() + '.' + ext);
        }
    }),
    fileFilter: (req, file, cb) => {
        const isValid = !!MIME_TYPE_MAP[file.mimetype];
        const error = isValid ? null : new Error('Invalid mime type!');
        cb(error, isValid);
    }
});

module.exports = fileUpload;
解决方案

1. 修正前端文件上传逻辑

前端中formState.inputs.image.value是文件输入框的路径字符串,不是File对象,multer无法解析这种格式,导致整个FormData解析失败,req.body为空。需要改为获取文件对象:

// 假设image是<input type="file" name="image">
formData.append('image', formState.inputs.image.files[0]);

2. 确认后端中间件顺序

当前路由中fileUpload.single('image')已经放在express-validator的body验证之前,这个顺序是正确的——multer需要先解析FormData,把文本字段存入req.body,后续的验证才能读取到数据。

3. 避免手动设置Content-Type头

fetch在发送FormData时会自动设置正确的Content-Type: multipart/form-data; boundary=xxx,手动设置该头会导致解析失败,保持代码中不添加headers配置即可。

4. 补充错误排查步骤

  • 检查uploads/images目录是否存在,multer需要该目录存在才能写入文件,否则会抛出错误导致500。
  • 在signup控制器中打印调试信息,确认multer解析结果:
const signup = (req, res, next) => {
  console.log('req.body:', req.body);
  console.log('req.file:', req.file);
  res.json({user: req.body, file: req.file})
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:31:06