简体   繁体   中英

Boostrap Ajax Modal with Google reCaptcha - call captcha challenge not working twice

I'm trying to implement a CTA form in a Bootstrap modal where the content is loaded asynchronously. So ever time I open the modal, its content is dynamically generated and inserted in the modal.

To render the captcha, I use the open event of the Bootstrap modal. Basically, I apply captcha only when the content of the modal is lodaed and displayed :

        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]);
            }
        });

Until here, no worries, the captcha icon is rendered in the bottom corner of the page showing the captcha is well applied on the form. Then, I would like to trigger the captcha challenge only when the form is valid on client side. So basically, on the click event of the button, I first check that the form is fully valid before to call grecaptcha.execute() method :

            $.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 {

This works perfectly at the first modal opening. The problem is when I close the modal and then re-open it, the captcha.render() does the job but then when trying to send the form after client validation, the grecaptcha.execute() is not challenging the user anymore.

I am sure the captcha methods are well applied and using the right IDs, because it works perfectly fine the first time. Looking more in detail on Google API side, I constat the following error in the recaptcha API when I try to use getResponse() just after rendering the captcha the second time :

Uncaught TypeError: Cannot read property 'value' of null

Indeed, in the following code :

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.

Then this block the sending of my form that never trigg the captcha challenge.

Let me precise that I try to reset the captcha at the close of the modal, this is well applied, but this doesn't change the problem.

I have try to be as clear as possible, not easy to summarize this kind of issue, any help would be greatly appreciated.

Best regards,

I had similar problem to you and I have found the solution. After close modal try to erase captcha config from global window like that:

window['___grecaptcha_cfg'] = undefined;

In our case that resolved the problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM