Search code examples
javascripthtmlrecaptcha

Why does Google ReCaptcha v2 checkbox break after >5min idle time on a mobile device?


I have Google ReCaptcha v2 Checkbox implemented in a ASP.NET Core 3.1 MVC application. It works fine on mobile and desktop - I am able to fill out a form, click Submit, a bootstrap confirmation modal comes up with the captcha, and I can confirm my submission.

However, on my mobile device (I tested Chrome and Brave browsers), if the form page is idle for >5 minutes, and then I fill out the form and pull up the confirmation modal, the captcha sometimes breaks and looks like this:

enter image description here

A gray box with a sad face. It's not a very descriptive error.

I tried both automatic rendering and explicit rendering for the captcha, but the issue persists.

My captcha html, which is inside a bootstrap modal that is initially not shown:

<div id="recaptcha" class="g-recaptcha" data-size="compact" data-sitekey="@ViewData["ReCaptchaKey"]"></div>

Code that explicitly renders captcha:

/**
 * Function gets called when the google recaptcha API loads. This is to ensure element is present in html before
 * initialising captcha.
 * More info: https://stackoverflow.com/a/46388681/12300287
 */
var _captchaTries = 0;
function recaptchaOnload() {
    _captchaTries++;
    if (_captchaTries > 9)
        return;
    if ($('.g-recaptcha').length > 0) {
        grecaptcha.render("recaptcha");
        return;
    }
    window.setTimeout(recaptchaOnload, 1000);
}

Script tag for captcha in the head:

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

As I said, I tried automatic render with captcha, making the code simpler, but the issue still exists.

EDIT: I'm working on another app with a reCAPTCHA and this still happens, but in this new case it's not when >5mins pass and it's not in a modal. The error seems to be uncommon and hard to recreate. Refreshing the page fixes it. The only pattern I noticed is it tends to appear when I visit the site on my phone after not having visited it in a while.


Solution

  • I still don't know what is the cause of this error but I found a way to handle it.

    Above the reCAPTCHA, you can add a button that calls grecaptcha.reset(); method:

    <input type="button" onclick="grecaptcha.reset();" value="Reload" />
    

    If the reCAPTCHA breaks, clicking the button resets it to working condition.