Express.js调用/bookroom接口返回400 Bad Request错误求助
400错误根因与修复方案
触发400 Bad Request的核心原因是Mongoose数据校验失败,具体问题点和修复方式如下:
- 字段名大小写不匹配:booking模型定义的必填交易号字段为全小写
transactionid,但后端路由创建预约记录时传的是驼峰写法transactionId,Mongoose字段名严格区分大小写,判定必填字段缺失直接抛错,进入catch分支返回400状态码,这是最主要的报错原因。 - 前端传参类型不匹配:前端传给后端的
fromdate、todate是moment实例对象,不符合模型定义的String类型要求;totalamount初始值为undefined,若用户在房间信息加载完成前点击预约按钮,会传空值触发Number类型校验失败。 - 代理配置校验:你的后端服务监听端口是5000,但报错里请求发往3000端口,需确认前端代理配置是否正确,将
/api前缀的请求转发到后端5000端口,避免请求打错位置。
分步修复操作
1. 统一后端字段命名
打开routes/bookingsRoute.js,修改创建Booking实例时的字段名,和模型保持完全一致:
const newbooking = new Booking({ room: room.name, roomid: room._id, userid, fromdate, todate, totalamount, totaldays, transactionid: '1234' // 修正字段名,原写法为transactionId,大小写不匹配 })
如果习惯用驼峰命名,也可以反向修改模型里的字段名,只要两边完全一致即可。
2. 修正前端传参格式
打开前端Bookingscreen.js,提交预约前把日期转成模型要求的字符串格式,同时增加空值校验,避免加载中提交无效参数:
async function bookRoom(){ // 新增前置校验,数据未加载完成时禁止提交 if (!room || !totalamount) { alert('房间信息加载中,请稍后重试') return } const bookingDetails = { room, userid: JSON.parse(localStorage.getItem('currentUser'))._id, fromdate: fromdate.format('DD-MM-YYYY'), // moment对象转字符串,匹配模型类型 todate: todate.format('DD-MM-YYYY'), // moment对象转字符串,匹配模型类型 totalamount, totaldays } try{ await axios.post('/api/bookings/bookroom', bookingDetails) alert('房间预约成功') }catch(error){ console.log(error) } }
3. 优化后端报错提示(便于后续排查)
当前后端catch分支只返回固定错误信息,排查问题时可以临时把错误详情返回,方便定位问题:
catch(error){ return res.status(400).json({ message: error.message }); }
修复完成后重启后端服务,清空前端缓存重试即可。
内容的提问来源于stack exchange,提问作者Labalbal
相关产品推荐
相关产品推荐

