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

Express PUT请求中req.body为undefined的问题求助

React/Node/Express 用户更新接口 req.body 为 undefined 问题

问题现象

执行PUT请求更新用户信息时,req.body始终返回undefined,URL参数可正常获取,响应状态码固定为200,但用户数据未按预期更新。控制台日志输出:

in controllers/user.ts, userId: 65d73ae14d1a69c64d6787e6
in controllers/user.ts, data: undefined

cURL请求示例

curl -X PUT -H "Content-Type: application/json" -d '{"alignment":"pro"}' http://localhost:5000/api/user/65d73ae14d1a69c64d6787e6

响应示例

{"user":{"_id":"65d73ae14d1a69c64d6787e6","ipAddress":"::ffff:127.0.0.1","alignment":"","createdAt":"2024-02-22T12:15:29.745Z","__v":0}}

相关代码

Redux Action 代码

export const updateUser = (userId: string, data: any) => async (dispatch: any) => {
  try {
    dispatch(setLoadingAction(true));

    const response = await fetch(`http://localhost:5000/api/user/${userId}`, {
      method: 'PUT',
      cache: 'no-cache',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data)
    });

    const updatedUser = await response.json();
    dispatch(updateUserAction(updatedUser.user));
  } catch (error) {
    dispatch(setErrorAction('error updating user!'));
  }
}

控制器端点代码

exports.updateUser = asyncHandler(async (req: any, res: any, next: any) => {
  const { userId } = req.params;
  console.log(req.body)
  const data = req.body;
  console.log('in controllers/user.ts, userId:', userId);
  console.log('in controllers/user.ts, data:', JSON.stringify(data));

  const user = await updateUser(userId, data);

  res.status(200).json({ user });
});

路由定义

import express, { Request, Response } from "express";
const router = express.Router();

const userController = require("../controllers/user");

// GET /user/:ipAddress
// router.post("/", userController.createUser);
router.get("/api/user", userController.getUser);
router.put("/api/user/:userId", userController.updateUser);

export { router };

Server 配置

(async () => {
  const port = env.PORT;
  app.use(express.json());
  app.use(bodyParser.json());
  app.use(bodyParser.urlencoded({ extended: false }));
  app.use('/api/user', userRouter);

  try {
    app.listen(port, () => {
      db.on("error", console.error.bind(console, "connection error:"));
      db.on("connected", function () {
        console.log("Connected to MongoDB");
      });
      console.log(`Server started at http://localhost:${port}`);
    });
  } catch (err) {
    const error = new Error("Request failed");
    console.log(err);
    throw error;
  } finally {
    console.log("Server started");
  }
})();

问题根源与修复方案

1. 路由挂载重复导致路径冲突

路由文件中已定义/api/user/:userId的PUT端点,但server.ts又将整个路由挂载到/api/user路径下,最终实际接口路径变为/api/user/api/user/:userId,与你请求的/api/user/:userId不匹配,导致请求未进入正确的控制器逻辑,同时req.body无法被正常解析。

修复:
修改路由文件,移除路径中的/api/user前缀:

import express, { Request, Response } from "express";
const router = express.Router();

const userController = require("../controllers/user");

router.get("/", userController.getUser);
router.put("/:userId", userController.updateUser);

export { router };

修改后,server.ts的/api/user挂载路径会与路由内的路径拼接,最终PUT接口路径为/api/user/:userId,与请求路径一致。

2. 重复使用JSON解析中间件

Express 4.16+ 已内置express.json(),与bodyParser.json()功能完全一致,重复添加可能导致解析异常。

修复:
移除bodyParser相关中间件,仅保留express.json():

(async () => {
  const port = env.PORT;
  app.use(express.json());
  // 移除以下两行重复的中间件
  // app.use(bodyParser.json());
  // app.use(bodyParser.urlencoded({ extended: false }));
  app.use('/api/user', userRouter);

  try {
    app.listen(port, () => {
      db.on("error", console.error.bind(console, "connection error:"));
      db.on("connected", function () {
        console.log("Connected to MongoDB");
      });
      console.log(`Server started at http://localhost:${port}`);
    });
  } catch (err) {
    const error = new Error("Request failed");
    console.log(err);
    throw error;
  } finally {
    console.log("Server started");
  }
})();

3. 验证数据库更新逻辑

确保数据库层的updateUser函数正确处理传入的data参数,比如使用findByIdAndUpdate时需设置{ new: true }以返回更新后的文档:

// 示例数据库更新函数
const updateUser = async (userId, data) => {
  return await User.findByIdAndUpdate(userId, data, { new: true, runValidators: true });
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 03:14:57