WooCommerce优惠券字段启用reCAPTCHA后AJAX请求未触发问题
WooCommerce购物车优惠券reCAPTCHA AJAX请求未触发的解决方案
问题概述
在WooCommerce购物车的优惠券字段中添加reCAPTCHA,实现了初始禁用「应用优惠券」按钮、验证通过后与服务器校验并启用按钮的逻辑,但AJAX请求完全未触发,网络面板中看不到请求记录。
核心问题排查及修复方案
以下是导致AJAX请求未触发的常见原因及对应修复:
1. 未引入Google reCAPTCHA官方脚本
仅添加reCAPTCHA容器但未加载Google的核心脚本,会导致reCAPTCHA无法初始化,回调函数onRecaptchaSuccess根本不会执行。
修复:在主题functions.php中添加脚本加载逻辑:
// 仅在购物车页面加载reCAPTCHA脚本 function load_recaptcha_script() { if (is_cart()) { wp_enqueue_script('google-recaptcha', 'https://www.google.com/recaptcha/api.js', array(), null, true); } } add_action('wp_enqueue_scripts', 'load_recaptcha_script');
2. ajaxurl变量未定义
WordPress默认仅在后台定义ajaxurl,前端页面需要手动全局声明该变量,否则jQuery.post(ajaxurl...)会因变量未定义而失败。
修复:在前端脚本前添加ajaxurl的全局声明:
var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
3. 脚本执行时机与函数作用域问题
页面加载时可能jQuery还未就绪,或者回调函数未处于全局作用域,导致reCAPTCHA无法找到回调函数。
修复:将脚本包裹在jQuery(document).ready()中,并确保回调函数全局可访问:
<script> var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>'; // 全局声明回调函数,确保reCAPTCHA能识别 window.onRecaptchaSuccess = function(response) { console.log('reCAPTCHA succeeded'); jQuery.post(ajaxurl, { action: 'verify_recaptcha', recaptchaResponse: response, }, function(data) { if (data.success) { enableApplyCouponButton(); } else { console.error('reCAPTCHA verification failed'); } }); } jQuery(document).ready(function($) { function enableApplyCouponButton() { var btn = $('button[name="apply_coupon"]'); btn.length && btn.removeAttr('disabled'); } function disableApplyCouponButton() { var btn = $('button[name="apply_coupon"]'); btn.length && btn.attr('disabled', 'disabled'); } // 初始禁用按钮 disableApplyCouponButton(); }); </script>
4. reCAPTCHA容器配置错误
检查data-sitekey是否替换为你的实际站点密钥,密钥错误会导致reCAPTCHA无法正常加载。
修改后完整代码示例
functions.php 补充后代码
// 加载reCAPTCHA脚本 function load_recaptcha_script() { if (is_cart()) { wp_enqueue_script('google-recaptcha', 'https://www.google.com/recaptcha/api.js', array(), null, true); } } add_action('wp_enqueue_scripts', 'load_recaptcha_script'); // ReCAPTCHA验证回调 function verify_recaptcha_callback() { $recaptcha_response = sanitize_text_field($_POST['recaptchaResponse']); $secret_key = 'MY_SECRET_KEY'; // 替换为你的实际密钥 $verification_response = wp_safe_remote_post('https://www.google.com/recaptcha/api/siteverify', array( 'body' => array( 'secret' => $secret_key, 'response' => $recaptcha_response, ), )); if (is_wp_error($verification_response)) { wp_send_json(array('success' => false, 'error' => '验证失败')); } $response_body = wp_remote_retrieve_body($verification_response); $response_data = json_decode($response_body); $response_data->success ? wp_send_json(array('success' => true)) : wp_send_json(array('success' => false, 'error' => '验证失败')); } add_action('wp_ajax_verify_recaptcha', 'verify_recaptcha_callback'); add_action('wp_ajax_nopriv_verify_recaptcha', 'verify_recaptcha_callback');
cart.php 优惠券区域修改后代码
<tr> <td colspan="6" class="actions"> <?php if ( wc_coupons_enabled() ) { ?> <div class="coupon"> <label for="coupon_code" class="screen-reader-text"><?php esc_html_e( '优惠券:', 'woocommerce' ); ?></label> <input type="text" name="coupon_code" class="input-text" id="coupon_code" value="" placeholder="<?php esc_attr_e( '优惠券代码', 'woocommerce' ); ?>" /> <button type="submit" class="button<?php echo esc_attr( wc_wp_theme_get_element_class_name( 'button' ) ? ' ' . wc_wp_theme_get_element_class_name( 'button' ) : '' ); ?>" name="apply_coupon" value="<?php esc_attr_e( '应用优惠券', 'woocommerce' ); ?>"><?php esc_html_e( '应用优惠券', 'woocommerce' ); ?></button> <?php do_action( 'woocommerce_cart_coupon' ); ?> <!-- reCAPTCHA容器 --> <div id="coupon-recaptcha" class="g-recaptcha" data-sitekey="MY_SITE_KEY" data-callback="onRecaptchaSuccess"></div> <!-- 处理脚本 --> <script> var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>'; window.onRecaptchaSuccess = function(response) { console.log('reCAPTCHA验证通过'); jQuery.post(ajaxurl, { action: 'verify_recaptcha', recaptchaResponse: response, }, function(data) { data.success ? enableApplyCouponButton() : console.error('reCAPTCHA服务器端验证失败'); }); } jQuery(document).ready(function($) { function enableApplyCouponButton() { var btn = $('button[name="apply_coupon"]'); btn.length && btn.removeAttr('disabled'); } function disableApplyCouponButton() { var btn = $('button[name="apply_coupon"]'); btn.length && btn.attr('disabled', 'disabled'); } disableApplyCouponButton(); }); </script> </div> <?php } ?> <!-- 更新购物车按钮及其他操作 --> <?php wp_nonce_field( 'woocommerce-cart', 'woocommerce-cart-nonce' ); ?> </td> </tr>
验证步骤
- 替换代码中的
MY_SECRET_KEY和MY_SITE_KEY为Google reCAPTCHA控制台获取的真实密钥。 - 清除浏览器缓存,刷新购物车页面。
- 完成reCAPTCHA验证后,查看控制台是否输出
reCAPTCHA验证通过,并检查网络面板是否有admin-ajax.php请求。
内容的提问来源于stack exchange,提问作者Scott Colling
相关产品推荐
相关产品推荐

