使用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
相关产品推荐
相关产品推荐

