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

Express/Node.js表单提交时req.body为空对象问题排查

问题根因

req.body始终为空的核心原因是Express 内置的请求体解析中间件不支持multipart/form-data格式:

  • express.json()仅解析Content-Type为application/json的请求
  • express.urlencoded()仅解析Content-Type为application/x-www-form-urlencoded的请求
    你前端通过fetch提交FormData对象时,浏览器会自动将请求头设置为multipart/form-data,这种格式Express默认不会处理,自然拿不到解析后的请求体。
    你之前修改form标签的enctype属性没有效果,是因为你已经通过event.preventDefault()拦截了表单默认提交行为,改为手动触发fetch请求,form标签上的配置不会对JS构造的请求生效。
    另外你代码里console.log(data.toString())打印出[object FormData]是正常现象,FormData的toString()方法不会输出内部存储的键值对,调试时需要遍历entries才能看到内容:
for (const [key, value] of data.entries()) {
  console.log(key, value)
}
修复方案

根据你的需求二选一即可:

方案1:改用urlencoded格式提交(适配当前无文件上传的场景)

你当前只有两个数字字段,没有文件上传需求,完全没必要使用FormData,修改前端提交代码即可,后端无需改动:

const form = document.getElementById("myForm");
form.addEventListener("submit", async (event) => {
  event.preventDefault();
  const formData = new FormData(event.target);

  fetch(event.target.action, {
    method: "POST",
    headers: {
      "Content-Type": "application/x-www-form-urlencoded"
    },
    body: new URLSearchParams(formData).toString(),
  })
   .then((res) => res.text())
   .then((resData) => {
     console.log(resData);
  });
});

修改后请求会走express.urlencoded中间件的解析逻辑,req.body可以正常拿到thing1和thing2的值。

方案2:保留multipart格式,新增对应解析中间件(适配后续有文件上传的场景)

如果后续需要在表单里加文件上传功能,必须使用multipart/form-data格式,需要额外安装multer中间件处理解析:

  1. 安装依赖
npm install multer
  1. 修改后端代码,引入multer并配置到对应路由:
const express = require("express");
const path = require("path");
const multer = require("multer");
// 无文件上传场景用默认内存存储即可
const upload = multer();
const PORT = process.env.PORT || 5000;
const app = express();

app.use(express.static(path.join(__dirname)));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 给接口加上multer的none()方法,解析不带文件的multipart请求
app.post("/submit-thing1and2", upload.none(), async (req, res) => {
  console.log("req.body", req.body);
  res.send(req.body);
});
app.get("/", (req, res) => {
  res.sendFile("./html/index.html", { root: __dirname });
});

app.listen(PORT, () => console.log(`Listening on ${PORT}`));

修改后前端代码无需调整,即可正常解析FormData提交的字段。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 19:54:16