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
相关产品推荐
相关产品推荐

