我目前正在开发一个 Express.js 应用程序,用户可以在其中将产品添加到购物车并删除它们。但是,我面临一个问题,产品删除功能似乎无法按预期工作。
以下是我的设置的简要概述:
我定义了一个 Express.js 路由,用于处理 POST 请求以从购物车中删除产品。 当用户单击产品的删除按钮时,它应该使用产品名称向“/remove-from-cart”端点发送 POST 请求。 在我的路由处理程序中,我从请求正文中检索产品名称,从会话购物车中筛选出相应的产品,然后将用户重定向回购物车页面。
这是我的购物车页面代码:
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Product Cart | BeautySpot - HTML Template for Beauty Salons</title>
<link rel="shortcut icon" href="images/favicon.ico">
<!-- STYLESHEETS : begin -->
<link rel="stylesheet" type="text/css" href="assets/css/general.css"><!-- Default styles generated from assets/scss/general.scss (do not edit) -->
<link rel="stylesheet" type="text/css" href="assets/css/color-schemes/default.css"><!-- Default color scheme generated from assets/scss/color-schemes/default.scss (change to other pre-defined or custom color scheme) -->
<link rel="stylesheet" type="text/css" href="style.css"><!-- Place your own CSS into this file -->
<!-- STYLESHEETS : end -->
</head>
<body>
<!-- WRAPPER : begin -->
<div id="wrapper">
<!-- HEADER : begin -->
<%- html.header %>
<!-- HEADER : end -->
<!-- CORE : begin -->
<div id="core" class="core--narrow">
<div class="core__inner">
<!-- PAGE HEADER : begin -->
<div class="page-header">
<div class="page-header__inner">
<div class="lsvr-container">
<div class="page-header__content">
<h1 class="page-header__title">Your Cart</h1>
<!-- BREADCRUMBS : begin -->
<div class="breadcrumbs">
<div class="breadcrumbs__inner">
<ul class="breadcrumbs__list">
<li class="breadcrumbs__item">
<a href="index.html" class="breadcrumbs__link">Home</a>
</li>
<li class="breadcrumbs__item">
<a href="product-archive.html" class="breadcrumbs__link">Store</a>
</li>
</ul>
</div>
</div>
<!-- BREADCRUMBS : end -->
</div>
</div>
</div>
</div>
<!-- PAGE HEADER : end -->
<!-- CORE COLUMNS : begin -->
<div class="core__columns">
<div class="core__columns-inner">
<div class="lsvr-container">
<!-- MAIN : begin -->
<main id="main">
<div class="main__inner">
<!-- PAGE : begin -->
<div class="page product-post-page product-post-order product-post-order--cart">
<div class="page__content">
<!-- PRODUCT CART : begin -->
<form class="product-cart" method="post" action="http://localhost:4000/checkout">
<!-- CART LIST : begin -->
<ul class="product-cart__list">
<% products.forEach(product => { %>
<!-- CART ITEM : begin -->
<li class="product-cart__item">
<!-- ITEM ITEM COL : begin -->
<div class="product-cart__item-col product-cart__item-col--thumb">
<!-- ITEM THUMB : begin -->
<p class="product-cart__item-thumb">
<a href="product-single.html" class="product-cart__item-thumb-link">
<img src="<%= product.image %>" class="product-cart__item-thumb-img" alt="<%= product.name %>">
</a>
</p>
<!-- ITEM THUMB : end -->
</div>
<!-- ITEM ITEM COL : end -->
<!-- ITEM ITEM COL : begin -->
<div class="product-cart__item-col product-cart__item-col--title">
<!-- ITEM TITLE : begin -->
<h4 class="product-cart__item-title">
<a href="product-single.html" class="product-cart__item-title-link"><%= product.name %></a>
</h4>
<!-- ITEM TITLE : end -->
<!-- ITEM STATUS : begin -->
<p class="product-cart__item-status product-cart__item-status--in-stock"><!-- You can use "in-stock", "on-order" and "unavailable" modifiers -->
<%= product.status %>
</p>
<!-- ITEM STATUS : end -->
</div>
<!-- ITEM ITEM COL : end -->
<!-- ITEM ITEM COL : begin -->
<div class="product-cart__item-col product-cart__item-col--quantity">
<!-- ITEM QUANTITY : begin -->
<p class="product-cart__item-quantity quantity-field">
<input type="text" class="quantity-field__input" value="1">
<button type="button" class="quantity-field__btn quantity-field__btn--add" title="Add one">
<span class="quantity-field__btn-icon" aria-hidden="true"></span>
</button>
<button type="button" class="quantity-field__btn quantity-field__btn--remove" title="Remove one">
<span class="quantity-field__btn-icon" aria-hidden="true"></span>
</button>
</p>
<!-- ITEM QUANTITY : end -->
</div>
<!-- ITEM ITEM COL : end -->
<!-- ITEM ITEM COL : begin -->
<div class="product-cart__item-col product-cart__item-col--price">
<!-- ITEM PRICE : begin -->
<p class="product-cart__item-price">
<%= product.price %>
</p>
<!-- ITEM PRICE : end -->
</div>
<!-- ITEM ITEM COL : end -->
<!-- ITEM ITEM COL : begin -->
<div class="product-cart__item-col product-cart__item-col--remove">
<!-- ITEM REMOVE : begin -->
<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>
<!-- ITEM REMOVE : end -->
</div>
<!-- ITEM ITEM COL : end -->
</li>
<!-- CART ITEM : end -->
<% }); %>
</ul>
<!-- CART LIST : end -->
<!-- CART SUMMARY : begin -->
<div class="product-cart__summary">
<!-- CART COUPON : begin -->
<p class="product-cart__coupon">
<input type="text" class="product-cart__coupon-input" placeholder="Coupon Code">
<button type="button" class="product-cart__coupon-btn lsvr-button lsvr-button--type-2">Apply Coupon</button>
</p>
<!-- CART COUPON : end -->
<!-- CART TOTAL : begin -->
<p class="product-cart__total">
<span class="product-cart__total-label">Total</span>
<strong class="product-cart__total-price">$121.60</strong>
</p>
<!-- CART TOTAL : end -->
</div>
<!-- CART SUMMARY : end -->
<!-- ORDER FOOTER : begin -->
<div class="product-order__footer">
<!-- FOOTER BACK : begin -->
<p class="product-order__footer-back">
<a href="product-archive.html" class="product-order__footer-back-link">Back to Store</a>
</p>
<!-- FOOTER BACK : end -->
<!-- FOOTER CHECKOUT : begin -->
<p class="product-order__footer-checkout">
<button type="submit" class="product-order__footer-checkout-btn lsvr-button">To Checkout</button>
</p>
<!-- FOOTER CHECKOUT : end -->
</div>
<!-- ORDER FOOTER : end -->
</form>
<!-- PRODUCT CART : end -->
</div>
</div>
<!-- PAGE : end -->
</div>
</main>
<!-- MAIN : end -->
</div>
</div>
</div>
<!-- CORE COLUMNS : end -->
</div>
</div>
<!-- CORE : end -->
<!-- FOOTER : begin -->
<%- html.footer %>
<!-- FOOTER : end -->
</div>
<!-- WRAPPER : end -->
<!-- SCRIPTS : begin -->
<script src="assets/js/jquery-3.5.1.min.js" type="text/javascript"></script>
<script src="assets/js/third-party-scripts.min.js" type="text/javascript"></script>
<script src="assets/js/scripts.js" type="text/javascript"></script>
<!-- SCRIPTS : end -->
</body>
</html>
这是我的
app.js
文件的相关部分:
app.post('/remove-from-cart', (req, res) => {
const { productName } = req.body;
// Remove the product from the session cart
if (req.session.cart) {
req.session.cart = req.session.cart.filter(product => product.name !== productName);
}
// Redirect back to the cart page
res.redirect('/cart');
});
但是,尽管实现了此功能,当我单击“删除”按钮时,它并没有从购物车中删除产品,而是将我重定向到结帐页面。
我正在努力弄清楚为什么产品删除没有按预期进行。有人可以帮我解决这个问题吗?任何见解或建议将不胜感激。谢谢!
您的问题是您有嵌套表单。将
<form>
嵌套在另一个中是无效的。相反,删除嵌套表单并尝试使用 formaction
,它将优先于 action
上的 <form>
,从而不再调用结帐重定向:
<form class="product-cart" method="post" action="http://localhost:4000/checkout">
...
<!-- ITEM REMOVE : begin -->
<div class="product-cart__item-col product-cart__item-col--remove">
<input type="hidden" name="productName" value="<%= product.name %>">
<button type="submit" class="product-cart__item-remove-btn" formaction="/remove-from-cart">
<span class="product-cart__item-remove-btn-icon" aria-hidden="true"</span>
</button>
</div>
...
</form>
现在的主要缺点是,从技术上讲,您仍然会提交父表单,因此所有输入的所有数据都将发送到服务器,而不仅仅是隐藏的输入。如果您在提交表单之前需要填充必填字段(您可以使用按钮上的
formvalidate
属性来解决),这也可能是一个问题。如果您需要更多控制,请考虑使用 JavaScript 来发出 POST 请求,而不是使用 fetch()
方法。