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

axios前端请求导致服务器req.body为undefined的问题求助

前端axios请求导致服务器req.body为undefined的排查与解决

问题背景

原本正常运行的服务突发异常:前端通过axios发送登录POST请求时,服务器端req.body始终返回undefined;但使用Postman以raw JSON格式发送相同请求时,服务器能正常解析请求体并返回响应。服务器已配置express.json()、express.urlencoded()等请求体解析中间件。

相关代码

前端axios请求代码

axios.post(
  `${process.env.REACT_APP_API_URI}/auth/signin`,
  {
    username: signinInfo.username,
    password: signinInfo.password,
  },
  { headers: { "Content-Type":"application/json"  },      
  }
)
.then((res) => {
  console.log(signinInfo.username);

  localStorage.setItem("accessToken", res.data.accessToken);
  localStorage.setItem(
    "subgatherUserInfo",
    JSON.stringify(res.data.data)
  );
  persistLogin(true);
  navigate("/");
})
.catch((err) => {
  console.log(signinInfo.password, signinInfo.username);
  mypageOn(false);
  setSigninInfo({ ...signinInfo, password: "" });
  setSigninErrMessage("아이디와 비밀번호를 정확히 입력해주세요");
  throw err;
});

Node.js服务器配置代码

const express = require("express");
const cors = require("cors");
const cookieParser = require("cookie-parser");
const app = express();
const Port = process.env.PORT || 5001;
const { authchecker } = require('./middleware/authChecker');
const authRouter = require('./routes/auth')
const userRouter = require('./routes/user');
const walletRouter = require('./routes/wallet')

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

app.use(
  cors({
    origin: [process.env.CLIENT_URL,"http://localhost:3000"],
    methods: ["GET", "POST", "PATCH", "DELETE"],
    credentials: true,
  })
);

app.use(authchecker)
app.use('/auth',authRouter)
app.use('/user',userRouter)
app.use('/wallet',walletRouter)

app.listen(Port, () => {
  console.log(`Server is Startin on ${Port}`);
});

登录路由处理代码

signinControl: async (req, res) => {
  const { username, password } = req.body;

  try {
    console.log(req.body,'login')

    const salt = await user.findOne({
      attributes: ["salt"],
      where: { username:username },
    });

    crypto.pbkdf2(
      password,
      salt.dataValues.salt,
      11011,
      64,
      "sha512",
      async (err, key) => {
        if (err) {
          throw err;
        }
        const hardPassword = key.toString("base64");

        const getUserInfo = await user.findOne({
          where: { username: username, password: hardPassword },
        });
        console.log(getUserInfo);

        if (!getUserInfo) {
          return res.status(401).send("이메일 및 비밀번호 확인");
        }
        const userUsername = getUserInfo.dataValues.username;
        const userNick = getUserInfo.dataValues.nickname;
        const userId = getUserInfo.dataValues.id;
        const isSocial = getUserInfo.dataValues.social_user;
        const isAdmin = getUserInfo.dataValues.isAdmin
        
        const accessToken = generateAccessToken({
          userUsername,
          userNick,
          userId,
          isAdmin,
          isSocial
        });
        const refreshToken = generateRefreshToken({
          userUsername,
          userNick,
          userId,
          isAdmin,
          isSocial
        });
        const accessExp = tokenExp(accessToken);
        const refreshExp = tokenExp(refreshToken);

        sendCookie(res, refreshToken);

        return res.status(200).send({
          data: {
            id: userId,
            nickname: userNick,
            username: userUsername,
            social_user:false,
            isAdmin:false,
            accessExp: accessExp,
            refreshExp: refreshExp,
          },
          accessToken: accessToken,
        });
      }
    );
  } catch (err) {
    return res.status(500).send(err);
  }
}

Postman成功请求示例

请求体(raw JSON):

{
  "username": "123456",
  "password": "123456456"
}

请求头Content-Type设置为application/json,成功响应:

{
  "data": {
    "id": 1,
    "nickname": "123456",
    "username": "123456456",
    "social_user": false,
    "isAdmin": false,
    "accessExp": 1658500545,
    "refreshExp": 1658748945
  },
  "accessToken": " "
}

排查与解决步骤

  1. 验证前端实际请求细节
    打开浏览器开发者工具(F12)→ Network标签,找到登录请求,检查:

    • 请求头Content-Type是否为application/json;charset=utf-8
    • Payload面板是否存在正确的JSON格式数据
  2. 检查全局axios拦截器
    确认前端是否有全局axios拦截器修改了请求头或请求体,比如误将Content-Type改为application/x-www-form-urlencoded,导致服务器用urlencoded解析JSON数据,最终req.body为空。可添加临时拦截器排查:

    axios.interceptors.request.use(config => {
      console.log('请求配置:', config.headers['Content-Type'], config.data);
      return config;
    });
    
  3. 排查authchecker中间件
    检查authchecker中间件是否提前消费了请求体(如调用req.read()或直接读取req.body但未正确传递),导致后续解析中间件无法处理请求体。

  4. 简化请求测试
    发送最简axios请求,排除环境变量、路由参数等干扰:

    axios.post('http://localhost:5001/auth/signin', {
      username: 'test',
      password: 'test'
    })
    .then(res => console.log(res))
    .catch(err => console.log(err));
    
  5. 确认环境变量正确性
    验证process.env.REACT_APP_API_URI指向的服务器地址与Postman一致,避免请求发送到错误服务。

常见根因

  • 前端请求Content-Type配置错误或被拦截器覆盖
  • 全局axios拦截器修改了请求体序列化方式
  • 中间件顺序错误(虽本次服务器配置顺序正确,但需确保解析中间件在路由前加载)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 16:27:35