页面上通过AJAX加载的reCAPTCHA字段;t负载.建议


reCAPTCHA field on page that is loaded through AJAX doesn't load. Suggestions?

实际示例:

  • 没有AJAX
  • 使用AJAX(单击"给我们发电子邮件"链接)

当我查看源页面时,一切都很好,但当我通过AJAX请求加载时,在reCAPTCHA应该的地方,我看到。。。

<noscript>
  <iframe src="http://www.google.com/recaptcha/api/noscript?k=6LfwkccSAAAAALr_z6vDBqkySowo5KIiR0mVM1BX" height="300" width="500" frameborder="0"></iframe><br/>
  <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
  <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
</noscript>

显然,除非我的用户禁用了JS,否则这不会有任何作用。在此过程中,不会引发任何错误。

查看代码上的非AJAX请求的速度,我看到。。。

<script type="text/javascript" src="http://www.google.com/recaptcha/api/challenge?k=6LfwkccSAAAAALr_z6vDBqkySowo5KIiR0mVM1BX"></script>
<noscript>
  <iframe src="http://www.google.com/recaptcha/api/noscript?k=6LfwkccSAAAAALr_z6vDBqkySowo5KIiR0mVM1BX" height="300" width="500" frameborder="0"></iframe><br/>
  <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
  <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
</noscript>

请注意脚本顶部的附加行,该行针对启用JS的用户。

所以我想问题有两个方面。WTF正在发生,我该如何解决?

我发现有人含糊地提到了这个问题,但没有像样的答案。我发现有人提到使用document.write的reCAPTCHA API,但我不知道这是否有效。如果我忽略了一些显而易见的东西,请随时指出。

根据请求,AJAX调用是…

$(document).ready(function() {
     $.get('/inc/email.php', 
           function(data){
                console.log('Get success!');
                $('#email-form').html(data);
                console.log('Get added to #email-form!');
                $('#email-form form').submit( function(){
                    $.ajax({
                      type: "POST",  
                      url: "/inc/email.php",  
                      data: $('#email-form form').serialize(),  
                      success: function() {
                            console.log('Submit success!');
                            $('#email-form').html(data);
                      }
                    });
                    return false;
                });
        }
     );
 });

到目前为止我所尝试的:

  • 重写代码以获取远程JS文件,将document.write()子句替换为对我设置为特定ID的元素的追加,然后在页面上内联运行修改后的代码
  • 显示没有插件的reCAPTCHA而不是PHP reCAPTCHA库

说明:

在使用AJAX时,这种情况之所以会中断,是因为jQuery在将HTML附加到DOM之前,会从HTML中剥离出任何script标记,并在全局上下文中对其进行评估。它不会将它与HTML的其余部分一起插入到DOM中。


在您的代码中:

代码中的罪魁祸首是这一行:

$('#email-form').html(data);

您正在获取从服务器接收的原始HTML字符串,并将其附加到DOM中。但是,jQuery首先从data变量中删除script标记,并在全局上下文中对其进行求值。

由于recaptcha.js脚本使用document.write将其内容添加到DOM,因此它会中断;document.write必须精确地运行在您希望它输出HTML的地方。


解决方案:

有两种可能的解决方案。

解决方案1:

不完全依赖jQuery,您可以使用普通JavaScript自己插入script标记,这将导致document.write在您想要的地方运行——就在DOM:中

success: function() {
    var form = $('#email-form')[0],
        script = $('<script src="http://www.google.com/recaptcha/api/challenge?k=6LfwkccSAAAAALr_z6vDBqkySowo5KIiR0mVM1BX" />')[0];
    form.appendChild(script);
}

注意这些行末尾的[0]。它们用于访问底层的原生DOM对象,这样我们就可以使用DOM的原生appendChild

解决方案2:

与其通过AJAX加载数据,不如考虑将其放在自己的页面中,然后在页面中插入一个iframe

success: function() {
    $('#email-form').html('<iframe src="path/to/reCAPTCHA/page.html" />');
}

您可以echo/inc/email.php文件中的所有内容!你必须事先包括所有必要的文件。