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

React前端POST请求Body为空问题(Postman可正常请求)

问题

搭建了React前端 + Express-Prisma Node.js后端架构,用Postman发送content-type: x-www-form-urlencoded的POST请求能正常执行,但前端通过Axios发起请求时,后端无法获取请求Body中的数据。

前端Axios POST代码

async function acceptCreateTask() {
const createTaskFormData = new FormData();

createTaskFormData.append("title", formValue.title);
createTaskFormData.append("category", formValue.category);
createTaskFormData.append("discription", formValue.discription);

try {
  const response = await axios({
    method: "post",
    url: "http://localhost:3001/task",
    data: createTaskFormData,
    headers: { "content-type": "application/x-www-form-urlencoded" },
  }).then((res) => {
    //
  });
} catch (error) {
       //
   }  
}

后端Express-Prisma处理代码

const { PrismaClient } = require("@prisma/client");
const prisma = new PrismaClient();

var cors = require("cors");
var express = require("express");
var app = express();

app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

//create a task
app.post("/task", async (req, res) => {
  console.log(req.body);

  const taskTitle = req.body.title;
  const taskCategory = req.body.category;
  const taskDiscription = req.body.discription;

  if (!req.body || !taskTitle || !taskCategory || !taskDiscription) {
    return res
      .status(400)
      .json({ message: "Title, categoy or discription is missing" });
  }

  try {
    const message = "Task created successfully";

    await prisma.task.create({
      data: {
        title: taskTitle,
        category: taskCategory,
        discription: taskDiscription,
      },
    });
    return res.json({ message });
  } catch (e) {
    return res.status(500).json({ message: "something went wrong" });
  }
});
原因分析

核心矛盾在于请求体格式与content-type头不匹配:

  • 用FormData构造请求体时,它默认对应multipart/form-data类型,但手动设置了x-www-form-urlencoded头,导致后端的express.urlencoded中间件无法解析这种混合格式的请求。
  • Postman能正常工作是因为直接构造了标准的x-www-form-urlencoded键值对,和后端解析逻辑完全匹配。
解决方案

方案一:使用URLSearchParams适配x-www-form-urlencoded格式

修改前端代码,用URLSearchParams代替FormData,它会自动生成符合x-www-form-urlencoded规范的请求体,Axios也会自动设置正确的请求头:

async function acceptCreateTask() {
  const params = new URLSearchParams();
  params.append("title", formValue.title);
  params.append("category", formValue.category);
  params.append("discription", formValue.discription);

  try {
    const response = await axios.post("http://localhost:3001/task", params);
    // 处理响应逻辑
  } catch (error) {
    // 处理错误逻辑
  }
}

后端代码无需修改,保持原有的express.urlencoded({ extended: true })即可。

方案二:后端支持multipart/form-data格式(保留FormData)

如果需要继续使用FormData,需在后端添加multer中间件解析multipart/form-data类型的请求:

  1. 安装multer依赖:
npm install multer
  1. 修改后端代码:
const { PrismaClient } = require("@prisma/client");
const prisma = new PrismaClient();
var cors = require("cors");
var express = require("express");
var multer = require("multer");
var app = express();

// 配置multer,仅解析字段不保存文件
const upload = multer({ storage: multer.memoryStorage() });

app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 用upload.none()解析FormData中的文本字段
app.post("/task", upload.none(), async (req, res) => {
  console.log(req.body);

  const taskTitle = req.body.title;
  const taskCategory = req.body.category;
  const taskDiscription = req.body.discription;

  if (!req.body || !taskTitle || !taskCategory || !taskDiscription) {
    return res
      .status(400)
      .json({ message: "Title, category or discription is missing" });
  }

  try {
    const message = "Task created successfully";

    await prisma.task.create({
      data: {
        title: taskTitle,
        category: taskCategory,
        discription: taskDiscription,
      },
    });
    return res.json({ message });
  } catch (e) {
    return res.status(500).json({ message: "something went wrong" });
  }
});
  1. 前端去掉手动设置的content-type头,让Axios自动处理:
async function acceptCreateTask() {
  const createTaskFormData = new FormData();
  createTaskFormData.append("title", formValue.title);
  createTaskFormData.append("category", formValue.category);
  createTaskFormData.append("discription", formValue.discription);

  try {
    const response = await axios.post("http://localhost:3001/task", createTaskFormData);
    // 处理响应逻辑
  } catch (error) {
    // 处理错误逻辑
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:01:17