为了账号安全,请及时绑定邮箱和手机立即绑定

如何更新 WooCommerce 购物车并在单个请求中返回新的 HTML?

如何更新 WooCommerce 购物车并在单个请求中返回新的 HTML?

PHP
弑天下 2021-12-03 18:49:26
我有一个自定义的“迷你购物车”,它具有购物车主页面的所有功能,即更改数量、删除项目、输入优惠券、删除优惠券。我目前正在监听change购物车form元素并通过 Ajax 提交(简化如下):ajaxTask = $.post(        $form.action, // this is a non-Ajax (front-end) URL, ie "/cart"        $form.serialize()    )    .done(function(data,status,jqXHR){        $cart.html(data);    });这会触发普通的 WC 表单处理程序,就好像update_cart单击了按钮一样(我添加<input type="hidden" name="update_cart" id="update_cart" value="1">到表单中是为了实现这一点)。问题是,“更新购物车”操作有一个内置的重定向,它应该重新加载页面。所以上面的函数返回整个页面。据我所知,没有其他函数可以简单地处理表单(无论是更改数量、删除项目、添加项目还是应用优惠券)并退出。将大部分表单处理程序复制/粘贴到我自己的代码中只是为了避免重定向,这似乎是一种笨拙/愚蠢/不好的做法。我希望服务器做的是:static function ajax_update_cart() {    // ( an action that updates the cart and outputs nothing )    echo cart_html(); // output the custom cart HTML    exit;}但我没有看到明显的方式。我确实了解购物车碎片,但这些碎片至少需要服务器往返两次。有没有办法提交购物车数据,更新购物车,然后返回我自己的 HTML?
查看完整描述

1 回答

?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

考虑到这一点后,我相信以下应该有效。对 wp_safe_redirect() 的调用将应用几个过滤器:'wp_safe_redirect_fallback'、'wp_redirect'、'wp_redirect_status',......任何这些都可以被滥用以防止发生 HTTP 重定向并返回您自己的 HTML。


add_filter('wp_safe_redirect_fallback', function($url) {

    if (/* wp_safe_redirect() is called from your cart update AJAX request */) {

        # Render your new cart HTML

        echo cart_html();

        # This filter cannot return otherwise wp_redirect() will be called!

        exit();

    }

    return $url;

}

注意,过滤器不是用作过滤器,而是用作更改 wp_safe_redirect() 执行的钩子,以不执行 HTTP 重定向并返回生成的 HTML。即调用 exit() 是必要的!


附录


我想到了另一种方法来实现这一目标。它再次涉及滥用过滤器。在这种情况下,过滤器“woocommerce_update_cart_action_cart_updated”将谎称正在更新购物车,从而阻止调用 wp_safe_redirect()。然后较低优先级的操作将生成更新的购物车 HTML。


add_filter( 'woocommerce_update_cart_action_cart_updated', function($cart_updated) {

    if (/* filter 'woocommerce_update_cart_action_cart_updated' is called from your cart update AJAX request */) {

        # returning false prevents the call to wp_safe_redirect()

        return false;

    }

    return $cart_updated;

} );


add_action( 'wp_loaded', function() {

    if (/* filter 'woocommerce_update_cart_action_cart_updated' is called from your cart update AJAX request */) {

        # need to calculate totals as this step was bypassed.

        WC()->cart->calculate_totals();

        # Render your new cart HTML

        echo cart_html();

        wp_die();

    }

}, 21 );   # priority 21 so this action runs after WC_Form_Handler::update_cart_action() which runs at priority 20



查看完整回答
反对 回复 2021-12-03
  • 1 回答
  • 0 关注
  • 213 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信