JavaScript购物车数量更新异常:移除按钮仍执行加1操作排查
购物车数量更新异常问题
- 当前状态:
- 点击
data-action="add"按钮:商品数量正常+1 - 点击
data-action="remove"按钮:商品数量仍执行+1操作,且未触发PATCH请求
- 点击
- 期望状态:
- 点击
data-action="add"按钮:商品数量+1 - 点击
data-action="remove"按钮:商品数量-1
- 点击
相关代码
const updateBtns = document.querySelectorAll(".update-cart"); const user = "{{request.user}}"; for (let i = 0; i < updateBtns.length; i++) { updateBtns[i].addEventListener("click", function () { event.preventDefault(); // 阻止页面刷新 const productId = this.dataset.product; const action = this.dataset.action; console.log("productId:", productId, "action:", action); console.log("USER:", user); createCart(productId, action); }); } function createCart(productId, action, cartId) { var csrftoken = getCookie('csrftoken'); console.log('User is logged in, sending data...'); fetch('/get_cart_id/') .then(response => response.json()) .then(data => { const cartId = data.cart_id; console.log('Cart ID:', cartId); // 控制台打印购物车ID // 获取对应购物车的条目 fetch(`/api/carts/${cartId}/items/`) .then(response => response.json()) .then(data => { let itemExists = false; let cartItemId = null; let quantity = 1; // 检查商品是否已在购物车中 for (let i = 0; i < data.length; i++) { if (data[i].product_id === parseInt(productId)) { itemExists = true; cartItemId = data[i].id; quantity = action === 'remove' ? data[i].quantity - 1 : data[i].quantity + 1; break; } } // 商品已存在则更新数量 if (itemExists) { fetch(`/api/carts/${cartId}/items/${cartItemId}/`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrftoken }, body: JSON.stringify({ quantity: quantity }) }) .then(response => response.json()) .then(data => { console.log('Item quantity updated:', data); }); } else { // 商品不存在则添加到购物车 fetch(`/api/carts/${cartId}/items/`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrftoken }, body: JSON.stringify({ product_id: productId, quantity: 1 }) }) .then(response => response.json()) .then(data => { console.log('Item added to cart:', data); }); } }); }); }
点击data-action="remove"按钮时的请求详情
get_cart_id/:返回有效购物车IDitems/:返回的购物车条目数据中,已存在目标商品的记录- 第二次
items/请求:执行了POST请求(而非预期的PATCH请求),新增了一条商品条目
问题定位与修复
核心原因
从请求行为可知,点击remove按钮时走了新增商品的POST逻辑,说明代码中itemExists被判定为false——遍历购物车条目时,没有匹配到目标商品ID。
问题出在类型不匹配的严格相等判断:
if (data[i].product_id === parseInt(productId))
返回的购物车数据中,product_id是字符串类型,而parseInt(productId)将按钮传递的productId转为了数字类型,===严格相等会因类型不同判定为不匹配,导致始终触发新增逻辑,数量自然+1。
修复方案
将判断条件修改为以下任一方式:
- 使用宽松相等比较(自动兼容类型):
if (data[i].product_id == parseInt(productId))
- 统一转为字符串类型比较:
if (data[i].product_id === productId.toString())
额外优化建议
- 避免重复请求购物车ID:可将获取到的cartId缓存,无需每次点击按钮都请求
/get_cart_id/ - 增加数量边界控制:remove操作时确保数量不小于1,避免出现负数或0:
quantity = action === 'remove' ? Math.max(data[i].quantity - 1, 1) : data[i].quantity + 1;
- 添加请求错误处理:给fetch添加
catch块,便于排查网络或接口错误:
fetch(`/api/carts/${cartId}/items/${cartItemId}/`, { ... }) .then(response => response.json()) .then(data => console.log('Item quantity updated:', data)) .catch(err => console.error('Update failed:', err));
内容的提问来源于stack exchange,提问作者David Henson
相关产品推荐
相关产品推荐

