Google "reCaptcha" sometimes doesn't get displayed/rendered

14,568

Solution 1

This problem appeared with me in google maps when initializing the map on hidden div (e.g. a modal). I'd solve this problem by removing the initialization from the page load and initialize each captcha when the modal is being displayed like that:

$(document).ready(function () {
    $('#loginModal').on('shown.bs.modal', function () {
        grecaptcha.render('RecaptchaField1', {'sitekey': '6LdbWAoTAAAAAPvS9AaUUAnT7-UKQMxz6vY4nonV'});
    })
    $('#loginModal').on('hide.bs.modal', function () {
        $("#RecaptchaField1").empty();
    })
});

Solution 2

If you have single page with this problem, remove "defer async" from recaptcha script load, and put "defer" on callback function.

Reason why you have problem is that loading remote scripts can last longer than loading other local scripts, so your render function is called before grecaptcha is fully loaded. When you remove defer async from remote script and put defer on callback, grecaptcha will be loaded during the page loading process and it will call callback function which will be triggered after page is completely loaded, so if you have no other "defer" marked scripts, grecaptcha.render() will be last thing to do on that page.

Code would look like this:

<script src='https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit'></script>

<script defer>
        var CaptchaCallback = function(){
            grecaptcha.render('htmlElementId', {'sitekey' : 'yourSiteKey'});
        };
</script>

Solution 3

I had a similar issue, but my captcha was not rendered and when I tried to call grecaptcha.getResponse() I saw the following error:

Error: Invalid ReCAPTCHA client id: undefined

In my case all custom scripts were included at the bottom of the HTML file, so I had a pure race condition that was mentioned by the recaptcha docs.

Note: your onload callback function must be defined before the reCAPTCHA API loads. To ensure there are no race conditions:

order your scripts with the callback first, and then reCAPTCHA use the async and defer parameters in the script tags (https://developers.google.com/recaptcha/docs/display)

With async and deferoptions the captcha failed 1 of 10 (or sometimes 1 of 30) reloads of the page. But when I removed them both - the situation became clear what was wrong. I hope this mention will be helpful for somebody.

Share:
14,568
Dexkill
Author by

Dexkill

Website: dennisrauscher.de Contact: [email protected] Programming Languages: C# (ASP.NET), Java, PHP (Laravel), JavaScript (Angular, JQuery) HTML, CSS Feel free to contact me in regards of software projects :)

Updated on July 18, 2022

Comments

  • Dexkill
    Dexkill almost 2 years

    Sometimes I have to reload the webpage multiple times till the reCaptcha gets rendered. I and a friend tested both on Firefox and Chrome but the problem is consistent and doesn't seem to depend on the used browser.

    The code I use to display my reCaptcha's:

     <script src='https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit' async defer></script>
    
    <script>
            var CaptchaCallback = function(){
                grecaptcha.render('RecaptchaField1', {'sitekey' : '6LdbWAo..'});
                grecaptcha.render('RecaptchaField2', {'sitekey' : '6LfAVAo..'});
                grecaptcha.render('RecaptchaField3', {'sitekey' : '6LfqWwo..'});
                grecaptcha.render('RecaptchaField4', {'sitekey' : '6Lf4sAo..'});
            };
    

    And later in the forms I just added: <div id="RecaptchaField1"></div> with the correct number.

    The forms are allways inside of a bootstrap modal if that cares?

    Edit: I deleted the async and defer atributes.

    Edit 2: Page that has the problems: http://www.dexquote.com

  • Peregring-lk
    Peregring-lk almost 8 years
    You should call grecaptcha.reset() first, before calling empty. I was having problems with that, although I don't remember why (and ensure, before calling reset, you called render once, because if you try to reset a non-existent recaptcha it throws an error).
  • JPB
    JPB about 6 years
    This does not work as is due to the render only being allowed to be performed once per load. It works but throws an error. The solution (if using jquery) is to change $('#loginModal').on to $('#loginModal').oneso the render is only added the first time the modal is opened. hide.bs.modal function can then be removed.