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

Axios Post请求返回400 Bad Request问题排查(React/Redux Toolkit/TS)

createAsyncThunk发起Axios POST请求返回400 Bad Request排查方案

400错误核心是服务端无法正确解析/处理客户端发送的请求,结合贴出的代码,按优先级排查以下问题:


核心问题点

  • 后端未配置JSON请求体解析中间件
    当前后端代码没有配置express.json()(Express 4.16+内置)或body-parser中间件,POST请求携带的JSON格式请求体不会被解析,req.body会是undefined,此时访问req.body.data会直接抛异常返回400错误,这也是Postman发JSON请求同样报400的最常见原因。
  • 请求缺少鉴权信息
    /createList路由绑定了requireSignin鉴权中间件,但前端Axios请求、Postman测试时都没有携带Authorization请求头(登录后拿到的有效token),会直接被鉴权中间件拦截返回4xx错误。
  • CORS配置位置与规则错误
    现有代码把CORS响应头写在了路由处理函数内部,请求如果被鉴权中间件拦截,根本走不到添加CORS头的逻辑;同时Access-Control-Allow-Headers只配置了authorization,缺少Content-Type,会导致浏览器发application/json请求时的OPTIONS预检直接失败。
  • 代码逻辑瑕疵(虽不直接触发400但会导致异常)
    • Axios请求没有加await关键字,try/catch无法捕获异步请求错误
    • 后端User.updateOne是异步操作,没有等待执行完成就提前返回响应,可能出现前端提示成功但数据库未更新的问题
    • 后端没有做参数判空,出错时无法返回明确的错误提示

修复步骤

1. 补全后端全局基础配置

在Express实例初始化后、所有路由注册前,添加以下配置:

// 解析JSON请求体
app.use(express.json())

// 全局CORS配置,不要写在单个路由处理函数里
app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
  // 补充允许Content-Type头
  res.header("Access-Control-Allow-Headers", "Authorization, Content-Type");
  // 直接放行OPTIONS预检请求
  if (req.method === "OPTIONS") return res.sendStatus(200);
  next();
})

// 之后再注册/signup、/createList等业务路由

2. 修正前端createAsyncThunk请求逻辑

补全鉴权头,修正异步写法:

export const createNewList = createAsyncThunk("myLists/createNewList", async (listData: listObject) => {
    try{
      // 从本地存储取登录时保存的鉴权token,键名和本地存储时保持一致
      const token = localStorage.getItem("authToken");
      const response = await axios.post(
        "http://localhost:3020/createList", 
        { data: listData },
        {
          headers: {
            // token格式和requireSignin中间件解析逻辑保持一致,一般为Bearer前缀
            "Authorization": `Bearer ${token}`,
            "Content-Type": "application/json"
          }
        }
      )
      // 记得抛出错误,否则createAsyncThunk无法触发rejected状态
      return response.data;
    }
    catch(error: any){
        console.log("请求错误:", error.response?.status, error.response?.data);
        throw error;
    }
})

3. 修正后端createList路由逻辑

增加参数校验,等待异步数据库操作完成再返回响应:

exports.createList = async function(req, res, next){
  try {
    // 参数判空,缺参时明确返回400
    if (!req.body?.data?.listMakerID) {
      return res.status(400).send({ error: "缺少必要的书单参数" });
    }
    const data = req.body.data;
    const userID = data.listMakerID;
    // 等待数据库操作完成再返回
    await User.updateOne({ uniqueID: userID }, { $push: { lists: data } });
    res.send("successful");
  } catch (err) {
    console.log("创建书单错误:", err);
    res.status(500).send({ error: "服务端处理失败" });
  }
}

验证顺序

  1. 先用Postman测试:请求体选raw -> JSON,传入完整的{"data": {对应listData结构对象}},请求头添加合法的Authorization值(从登录接口返回结果中获取),先测通Postman再调试前端
  2. 如果Postman不带token返回400/401,就是鉴权中间件拦截,必须传入有效token才能通过
  3. 如果带了token还是400,查看后端控制台报错,如果出现Cannot read property 'data' of undefined,说明JSON解析中间件没有配置生效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 10:36:24