求解决:Express req.params.itemId返回字面量":itemId"而非实际商品ID
问题根源
参数不生效的核心原因是前端请求地址没有做动态插值:
后端定义的路由/add-to-cart/:itemId中,:itemId是Express的路由参数占位符,需要前端发请求时替换成真实的商品id。但你在编写fetch请求时,直接把字面量字符串:itemId硬编码进了请求地址,完全没有把组件props里的真实itemId拼接进去,因此后端收到的req.params.itemId自然就是固定的字符串:itemId,和你控制台的输出结果完全吻合。
修复方案
1. 修正前端fetch的请求地址
把AddToCart组件里的请求地址从硬编码形式:
`http://localhost:8090/auth/add-to-cart/:itemId`
改成动态插值props值的形式:
`http://localhost:8090/auth/add-to-cart/${this.props.itemId}`
修改后发出的请求地址会是类似http://localhost:8090/auth/add-to-cart/650abc123xxx的真实路径,后端才能通过req.params.itemId拿到正确的商品id。
2. 补充避免表单默认行为的逻辑
因为你的按钮嵌在<form>标签内部,点击时默认会触发表单原生提交,和编写的异步fetch逻辑产生冲突,需要给点击事件加阻止默认行为的处理:
// 修改按钮绑定,传入事件对象 <button onClick={(e) => this.addToCart(e)}>Add To Cart</button> // 在addToCart方法开头阻止表单默认提交 addToCart = async (e) => { e.preventDefault(); // 原有fetch逻辑保持不变 await fetch(`http://localhost:8090/auth/add-to-cart/${this.props.itemId}`, { method: 'GET', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, credentials: 'include', }) .then(() => { return window.location.replace('/shop'); }) .catch(err => console.log(err)); }
之前尝试失效的原因
- 尝试用
req.body获取id不生效:你发的是GET请求,且fetch请求完全没有关联表单内容,form标签内写的hidden输入框的值根本没有被传递到请求体中,req.body自然拿不到任何值;如果要走POST/PATCH请求读req.body的逻辑,需要额外在fetch配置里把序列化后的itemId放到请求body字段,不能依赖表单原生提交。 - 尝试换query传参不生效:同样是因为前端没有把真实的itemId拼接到query参数中,哪怕后端路由改成了query接收的形式,前端传的还是固定字符串,自然无法获取正确值。
- 修改请求方法不生效:请求方法只是接口的访问语义,不解决你没有把真实id传到请求里的核心问题。
控制器的逻辑补全
你当前编写的addToCart控制器存在逻辑缺失:拿到正确的item和user之后,没有执行购物车的写入操作,也没有给前端返回响应,哪怕参数正确,接口也会一直挂起到超时。需要补充类似逻辑:
exports.addToCart = async (req, res, next) => { try { const userId = req.session.user._id.toString(); const user = await User.findById(userId); const itemId = req.params.itemId; const item = await Item.findById(itemId); // 把商品加入用户购物车数组 user.cart.push({ itemId: item._id }); await user.save(); // 给前端返回响应 res.redirect('/shop'); } catch (err) { console.log(err); if(!err.statusCode) { err.statusCode = 500; } next(err); } };
注:你在组件里写的hidden input是多余的,商品id已经通过props传递到组件内部,直接插值使用即可,不需要靠表单字段携带。
内容的提问来源于stack exchange,提问作者msorr95
相关产品推荐
相关产品推荐

