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

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/:返回有效购物车ID
  • items/:返回的购物车条目数据中,已存在目标商品的记录
  • 第二次items/请求:执行了POST请求(而非预期的PATCH请求),新增了一条商品条目
问题定位与修复

核心原因

从请求行为可知,点击remove按钮时走了新增商品的POST逻辑,说明代码中itemExists被判定为false——遍历购物车条目时,没有匹配到目标商品ID。

问题出在类型不匹配的严格相等判断:

if (data[i].product_id === parseInt(productId))

返回的购物车数据中,product_id是字符串类型,而parseInt(productId)将按钮传递的productId转为了数字类型,===严格相等会因类型不同判定为不匹配,导致始终触发新增逻辑,数量自然+1。

修复方案

将判断条件修改为以下任一方式:

  1. 使用宽松相等比较(自动兼容类型):
if (data[i].product_id == parseInt(productId))
  1. 统一转为字符串类型比较:
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 09:05:32