WooCommerce Ajax调用返回空配送包裹及配送区域问题求助
解决WooCommerce Ajax请求无法获取配送包裹/区域的问题
问题描述
通过Ajax获取WooCommerce的配送包裹(WC()->shipping->get_packages())时始终返回空值,调用WC_Shipping_Zones::get_zones()获取配送区域也出现同样问题,但在woocommerce_checkout_before_order_review钩子中运行相同代码却能正常返回数据。
原代码及返回结果
PHP代码
function jsforwp_add_like() { check_ajax_referer( 'jsforwp_likes_nonce' ); $packages = WC()->shipping->get_packages(); if(empty($packages)){ $check = 'empty'; }else{ $check = $packages; } $success = true; if( true == $success ) { $response['type'] = 'success'; $response['zone'] = $check; } $response = json_encode( $response ); echo $response ; die(); } add_action( 'wp_ajax_jsforwp_add_like', 'jsforwp_add_like' ); add_action( 'wp_ajax_nopriv_jsforwp_add_like', 'jsforwp_add_like' );
JavaScript代码
add_action('wp_footer','my_custom_ajax'); function my_custom_ajax(){ ?> <script> (function($){ $( document.body ).on( 'updated_checkout', function(){ $.ajax({ type : 'post', dataType : 'json', url : jsforwp_globals.ajax_url, data : { action: 'jsforwp_add_like', _ajax_nonce: jsforwp_globals.nonce }, success: function( response ) { if( 'success' == response.type ) { console.log( response ); } else { console.log( 'Something went wrong, try logging in!' ); } } }); } ); } )( jQuery ); </script> <?php }
返回结果
{type: "success", zone: "empty"}
问题原因
Ajax请求的运行上下文与结账页面钩子不同:
woocommerce_checkout_before_order_review触发时,WooCommerce的购物车会话、用户配送地址等数据已完成初始化,能正常计算配送包裹和区域。- 独立的Ajax请求中,WooCommerce会话未自动初始化,且缺少用户配送地址等必要数据,导致无法生成配送包裹。
解决方案
1. 修改PHP回调函数,初始化会话与购物车
在Ajax回调中手动初始化WooCommerce会话,确保购物车和用户数据加载完成:
function jsforwp_add_like() { check_ajax_referer( 'jsforwp_likes_nonce' ); // 初始化用户会话 if ( ! WC()->session->has_session() ) { WC()->session->set_customer_session_cookie( true ); } // 加载购物车数据 WC()->cart->get_cart(); // 若前端未传递地址,可设置默认配送地址(示例) if ( empty( WC()->customer->get_shipping_country() ) ) { WC()->customer->set_shipping_country( 'CN' ); WC()->customer->save(); } $packages = WC()->shipping->get_packages(); $check = empty($packages) ? 'empty' : $packages; // 使用wp_send_json规范返回JSON wp_send_json( array( 'type' => 'success', 'zone' => $check ) ); } add_action( 'wp_ajax_jsforwp_add_like', 'jsforwp_add_like' ); add_action( 'wp_ajax_nopriv_jsforwp_add_like', 'jsforwp_add_like' );
2. 优化JS代码,传递用户配送地址
从结账页面表单中获取用户已填写的配送地址,随Ajax请求传递,确保WooCommerce能精准计算配送包裹:
add_action('wp_footer','my_custom_ajax'); function my_custom_ajax(){ ?> <script> (function($){ $( document.body ).on( 'updated_checkout', function(){ // 获取结账页面的配送地址字段值 const shippingInfo = { shipping_country: $('select[name="shipping_country"]').val(), shipping_state: $('select[name="shipping_state"]').val(), shipping_postcode: $('input[name="shipping_postcode"]').val() }; $.ajax({ type : 'post', dataType : 'json', url : jsforwp_globals.ajax_url, data : { action: 'jsforwp_add_like', _ajax_nonce: jsforwp_globals.nonce, ...shippingInfo // 合并配送地址参数 }, success: function( response ) { if( 'success' == response.type ) { console.log( response ); } else { console.log( '出错了,请重试!' ); } } }); }); })( jQuery ); </script> <?php }
关键说明
WC()->session->set_customer_session_cookie(true):确保用户会话被正确初始化,这是WooCommerce加载用户数据的前提。WC()->cart->get_cart():强制加载购物车数据,避免因购物车未初始化导致的空值问题。- 传递配送地址:配送包裹和区域的计算依赖用户的配送地址,传递真实地址能获取到精准的配送数据。
内容的提问来源于stack exchange,提问作者Ibtekarlabs
相关产品推荐
相关产品推荐

