使用Google reCaptcha进行Boostrap Ajax模式调用 - 调用验证码挑战无法工作两次

时间:2017-04-25 12:12:33

标签: javascript jquery twitter-bootstrap api recaptcha

我试图在Bootstrap模式中实现CTA表单,其中内容是异步加载的。 所以,每当我打开模态时,它的内容都会动态生成并插入到模态中。

要渲染验证码,我使用Bootstrap模式的open事件。基本上,我只在模态的内容被丢失并显示时应用验证码:

        self.$modal.on('shown.bs.modal', function () {
            $('.bootstrap.modal-backdrop.fade.in').css("z-index", 1059);
            var form = $("#cta-modal-holder form.callToAction");
            var captchaCheckNeeded = form.attr('data-captcha');


            //Check if we need to apply captcha on the form
            if (captchaCheckNeeded.toLowerCase() == 'true') {
                //This apply the render() method on the form using an invisible <div>
                IMD.Website.Cms.GoogleCaptcha(form[0]);
            }
        });

直到这里,不用担心,验证码图标会显示在页面的下角,显示验证码已在表单上得到很好的应用。然后,我想仅在表单在客户端有效时才触发验证码挑战。所以基本上,在按钮的click事件上,我首先检查表单是否完全有效,然后再调用grecaptcha.execute()方法:

            $.when($form.isFormValidAsync()).then(function (isValid) {
                //First we perform the classic form client validation, only if this IsValid, then we perform the captcha validation
                if (isValid) {
                    //If captchaCheckNeeded == true, then we execute the Captcha
                    //Here, two behaviours possible from client side :
                    // - 1. User is not suspected as a BOT, captcha check is executed and return the token transparently from the user and form is sent automatically
                    // - 2. User is suspected as a BOT, then the captcha modal is showed to the visitor that has to fill the captcha challenge.
                    //      Only when the challenge is validated, then the form is sent because of the Captcha callback function.
                    if (captchaCheckNeeded.toLowerCase() == 'true') {
                        var holder = $form[0].querySelector('.recaptcha-holder');
                        grecaptcha.execute(holder[0]);
                        $submitBtn.prop('disabled', false);
                    }else{
                        $form.trigger('submit', { buttonSubmit: true });
                    }
                } else {

这在第一次模态开启时非常有效。问题是当我关闭模式然后重新打开它时,captcha.render()完成工作,但是当在客户端验证后尝试发送表单时,grecaptcha.execute()不再对用户提出质疑。

我确信验证码方法已得到很好的应用并使用了正确的ID,因为它第一次运行得非常好。 在Google API方面详细了解,当我第二次渲染验证码后尝试使用getResponse()时,我在recaptcha API中发出以下错误:

未捕获的TypeError:无法读取属性&#39;值&#39;为null

确实,在以下代码中:

var Do = function(a) {
    var b = window.___grecaptcha_cfg.clients[a || 0];
    if (!b)
        throw Error("Invalid ReCAPTCHA client id: " + a);
    return vg(qo(b.id)).value
}

//Here, vg(qo(b.id)) represents the field g-recaptcha-response at the first 
call of the getResponse() method.
//At the second call, this value is null, even if I clearly see the field in 
my form after calling the render() method.

然后阻止发送我的表格,从不触发验证码挑战。

让我确切地说,我尝试在模态结束时重置验证码,这很好用,但这并没有改变问题。

我尽量保持清晰,不容易总结这类问题,我们将非常感谢任何帮助。

致以最诚挚的问候,

1 个答案:

答案 0 :(得分:1)

我遇到了类似的问题,我找到了解决方案。关闭模态后尝试从全局窗口中删除captcha配置,如:

window['___grecaptcha_cfg'] = undefined;

在我们解决问题的案例中。