Contact Form 7搭配reCAPTCHA在AJAX加载场景下的异常问题
解决AJAX动态加载Contact Form 7时reCAPTCHA不加载的问题
我之前在做WooCommerce可变产品项目时,碰到过完全一样的问题——动态加载的CF7表单reCAPTCHA死活不出来,导致表单提交失败。给你两个经过实测的解决方案:
方案一:监听变体切换事件,手动初始化CF7
这个是最直接有效的方法,核心思路是在WooCommerce加载完变体(也就是你的CF7表单被插入页面后),调用CF7内置的初始化函数,触发reCAPTCHA渲染。
步骤1:添加前端JS代码
把这段代码放到你的主题functions.php里,或者通过自定义插件添加:
add_action('wp_footer', function() { ?> <script> jQuery(document).ready(function($) { // 监听WooCommerce变体加载完成事件 $('form.variations_form').on('found_variation', function(event, variation) { // 定位到动态加载的CF7表单容器 const $cf7Form = $(this).find('.wpcf7-wrapper .wpcf7-form'); if ($cf7Form.length && typeof wpcf7 !== 'undefined') { // 初始化CF7表单,包括reCAPTCHA wpcf7.init($cf7Form); // 如果用的是reCAPTCHA v3,额外触发验证(v2不需要这步) if (typeof wpcf7.recaptcha !== 'undefined') { wpcf7.recaptcha.execute(); } } }); }); </script> <?php });
步骤2:确保CF7脚本在产品页面加载
有时候CF7会只在有表单的页面加载脚本,产品页面默认没有,所以需要强制加载:
add_action('wp_enqueue_scripts', function() { // 强制加载CF7的核心脚本和样式 if (function_exists('wpcf7_enqueue_scripts')) { wpcf7_enqueue_scripts(); } if (function_exists('wpcf7_enqueue_styles')) { wpcf7_enqueue_styles(); } });
方案二:修改PHP代码,延迟加载CF7表单
如果方案一还是有问题,可以换个思路:不直接在变体数据里输出CF7短代码,而是输出一个占位符,然后用JS动态请求CF7表单内容并插入,这样能确保脚本初始化更彻底。
修改你的PHP代码:
add_filter( 'woocommerce_available_variation', 'empty_and_zero_variation_prices_html', 10, 3); function empty_and_zero_variation_prices_html( $data, $product, $variation ) { if( '0' === $variation->get_price() || '' === $variation->get_price() || 0 == $variation->get_price() ){ // 输出占位符,而不是直接渲染CF7 $data['price_html'] = __(' <div class="wpcf7-wrapper"> <h5 class="text-primary font-weight-bold">Kontakta oss angående produkten</h5> <div class="cf7-placeholder" data-form-id="7336"></div> </div> ', 'woocommerce'); $data['is_purchasable'] = false; } else { $data['price_html'] .= __(do_shortcode( '[add_to_cart_button]' )); } return $data; }
对应前端JS代码:
add_action('wp_footer', function() { ?> <script> jQuery(document).ready(function($) { $('form.variations_form').on('found_variation', function(event, variation) { const $placeholder = $(this).find('.cf7-placeholder'); if ($placeholder.length && !$placeholder.hasClass('loaded')) { const formId = $placeholder.data('form-id'); // 用AJAX请求CF7表单内容 $.ajax({ url: ajaxurl, type: 'POST', data: { action: 'load_cf7_form', form_id: formId }, success: function(response) { if (response.success) { $placeholder.html(response.data).addClass('loaded'); // 初始化CF7 if (typeof wpcf7 !== 'undefined') { wpcf7.init($placeholder.find('.wpcf7-form')); if (typeof wpcf7.recaptcha !== 'undefined') { wpcf7.recaptcha.execute(); } } } } }); } }); }); </script> <?php }); // 添加AJAX处理函数 add_action('wp_ajax_load_cf7_form', 'load_cf7_form'); add_action('wp_ajax_nopriv_load_cf7_form', 'load_cf7_form'); function load_cf7_form() { $formId = isset($_POST['form_id']) ? intval($_POST['form_id']) : 0; if ($formId > 0) { $formHtml = do_shortcode("[contact-form-7 id='{$formId}' title='Prisförfrågan']"); wp_send_json_success($formHtml); } wp_send_json_error('Invalid form ID'); }
注意事项
- 测试前清空浏览器缓存,确保新的JS代码生效。
- 打开浏览器控制台,检查有没有
wpcf7未定义的报错,如果有,说明CF7脚本没加载,方案一里的强制加载代码一定要加。 - 如果你用的是reCAPTCHA v2,方案一里的
wpcf7.recaptcha.execute()可以去掉,v2会自动渲染出验证框。
内容的提问来源于stack exchange,提问作者Webking
相关产品推荐
相关产品推荐

