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

Express.js应用购物车商品移除功能失效问题求助

问题排查与修复

核心问题:HTML表单嵌套违规

你的移除按钮表单嵌套在父购物车表单(action="http://localhost:4000/checkout")内部,而HTML规范不允许表单嵌套。浏览器会自动忽略内部的<form>标签,点击移除按钮时实际提交的是父表单,所以才会跳转到结账页面,根本没触发/remove-from-cart路由。

修复方案

方案1:重构表单结构,避免嵌套

把移除按钮的独立表单移到父表单之外,或者将父购物车的表单拆分:

<!-- 原父表单改成普通div -->
<div class="product-cart">
    <!-- 购物车列表部分不变 -->
    <ul class="product-cart__list">
        <% products.forEach(product => { %>
        <li class="product-cart__item">
            <!-- ... 其他商品信息 ... -->
            <div class="product-cart__item-col product-cart__item-col--remove">
                <form action="/remove-from-cart" method="POST">
                    <input type="hidden" name="productName" value="<%= product.name %>">
                    <button type="submit" class="product-cart__item-remove-btn">
                        <span class="product-cart__item-remove-btn-icon" aria-hidden="true"></span>
                    </button>
                </form>
            </div>
        </li>
        <% }); %>
    </ul>

    <!-- 结账按钮单独做一个表单 -->
    <form method="post" action="http://localhost:4000/checkout">
        <!-- 购物车摘要、优惠券部分不变 -->
        <div class="product-cart__summary">...</div>
        <div class="product-order__footer">
            <p class="product-order__footer-back">...</p>
            <p class="product-order__footer-checkout">
                <button type="submit" class="product-order__footer-checkout-btn lsvr-button">To Checkout</button>
            </p>
        </div>
    </form>
</div>

方案2:用AJAX提交移除请求(推荐)

保留原结构,通过JavaScript拦截移除按钮的点击事件,用AJAX发送POST请求,避免表单提交跳转:

// 在页面的<script>标签或scripts.js中添加
document.querySelectorAll('.product-cart__item-remove-btn').forEach(btn => {
    btn.addEventListener('click', async (e) => {
        e.preventDefault(); // 阻止默认表单提交
        const form = btn.closest('form');
        const productName = form.querySelector('input[name="productName"]').value;
        
        try {
            await fetch(form.action, {
                method: form.method,
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: `productName=${encodeURIComponent(productName)}`
            });
            // 请求成功后刷新页面或更新购物车DOM
            window.location.href = '/cart';
        } catch (err) {
            console.error('移除商品失败:', err);
        }
    });
});

额外检查点

  1. 确认Express已配置body解析中间件:如果没有解析表单数据,req.body.productName会是undefined,过滤逻辑无效。在app.js中添加:
app.use(express.urlencoded({ extended: true })); // 解析x-www-form-urlencoded格式的表单数据
  1. 验证商品名称匹配度:确保req.session.cart中商品的name字段和提交的productName完全一致(注意大小写、空格、特殊字符),可以在路由中加日志排查:
app.post('/remove-from-cart', (req, res) => {
  const { productName } = req.body;
  console.log('收到移除请求,商品名称:', productName);
  console.log('当前购物车:', req.session.cart);

  if (req.session.cart) {
      req.session.cart = req.session.cart.filter(product => product.name !== productName);
      console.log('移除后购物车:', req.session.cart);
  }

  res.redirect('/cart');
});

内容的提问来源于stack exchange,提问作者FFFFFFFFF

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 13:17:02