3

活生生的例子:

当我查看源页面时,一切正常,但是当我通过 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 正在发生,我该如何解决?

我发现一些关于这个问题的模糊提及,但没有像样的答案。我发现有人提到了 reCAPTCHA API using document.write,但我不知道这是否有效。如果我忽略了一些明显的东西,请随时指出。

根据请求,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;
                });
        }
     );
 });

到目前为止我所尝试的:

4

2 回答 2

8

解释:

使用 AJAX 执行此操作时会中断的原因是,jQueryscript在将 HTML 附加到 DOM 之前会从 HTML 中去除任何标签,并在全局上下文中对其进行评估。它不会将它与 HTML 的其余部分一起插入到 DOM 中。


在您的代码中:

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

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

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

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


解决方案:

有 2 种可能的解决方案。

解决方案#1:

您可以使用 vanilla JavaScript 自己插入标签,而不是完全依赖 jQuery 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" />');
}
于 2012-07-30T22:20:00.107 回答
0

您可以在/inc/email.php文件中显所有内容!您必须提前包含所有必要的文件。

于 2012-07-30T23:04:16.777 回答