209

I have a signup form with AJAX so that I want to refresh Recaptcha image anytime an error is occured (i.e. username already in use).

I am looking for a code compatible with ReCaptcha to reload it using JavaScript.

ahmet alp balkan
  • 42,679
  • 38
  • 138
  • 214
  • 1
    Don't bother. Why change the CAPTCHA if the username is taken? – SLaks Jul 30 '10 at 12:25
  • 20
    *@SLaks*: probably because he first checks captcha and then checks the user - and once captcha is used, it is no longer valid. Doing this the other way around the malicious user can easily flaw the server and get the list of all users using brute force without being bothered with captcha. – Tomasz Nurkiewicz Oct 11 '11 at 09:50
  • 1
    @TomaszNurkiewicz UPDATE: the malicious user won't be able to submit the same re-captcha for validation more than once. So no, bruteforce is not possible here. The reason for refreshing the captcha is to simply allow the user to enter it again. – tonysepia Sep 14 '17 at 16:11
  • I believe a skilled attacker could exploit timing attacks to find what data is wrong depending on where the bot validation is; I prefer to keep mine as the first check and immediately reject anything if they fail, also helps reduce the load on my server so I'm not doing DB queries when they will be rejected anyways – Steve Byrne Oct 16 '18 at 04:33

9 Answers9

422

For reCaptcha v2, use:

grecaptcha.reset();

If you're using reCaptcha v1 (probably not):

Recaptcha.reload();

This will do if there is an already loaded Recaptcha on the window.

(Updated based on @SebiH's comment below.)

ahmet alp balkan
  • 42,679
  • 38
  • 138
  • 214
  • 21
    For anyone using the new reCAPTCHA: The line has now changed to `grecaptcha.reset();` ([documenation](https://developers.google.com/recaptcha/docs/display#config)) – SebiH Jan 06 '15 at 08:36
  • i'm using this `grecaptcha.reset();` for my react apps, and it works perfectly – yussan Apr 16 '16 at 16:41
  • 4
    if you are not sure grecaptcha is loaded, use `if (window.grecaptcha) grecaptcha.reset();` – fred727 Jul 19 '16 at 19:39
  • Although this reloads the captcha, the field value for the captcha response doesn't appear to be removed, leaving my form valid. – Damian Green Sep 28 '16 at 12:51
72

If you are using version 1

Recaptcha.reload();

If you are using version 2

grecaptcha.reset();
Dasun
  • 3,244
  • 1
  • 29
  • 40
  • 3
    Copied the accepted answer and reposted 3 years later. Urg. – Paul Danelli Feb 26 '20 at 14:03
  • 2
    @PRWhitehead Please see the edit history. BTW, thanks for the down vote. – Dasun Feb 28 '20 at 12:39
  • I did, you've not edited yours, and you first added it 3 months after the accepted answer was updated to reflect a change to the API - affecting the relevance of the initial answer and years after it was first added. I downvoted it because this the accepted answer is more useful. – Paul Danelli Feb 29 '20 at 18:08
  • 3
    I added this answer because I faced, the same issue. Though the accepted answer reflected the correct answer at the time it was not clear enough. At least for me, that's why I decided to add as a new answer with clear separation (the accepted answer did fail to note the differences against the versions). – Dasun Mar 01 '20 at 10:50
53

Important: Version 1.0 of the reCAPTCHA API is no longer supported. Please upgrade to Version 2.0.

You can use grecaptcha.reset(); to reset the captcha.

Source: https://developers.google.com/recaptcha/docs/display#js_api

Tes3awy
  • 2,166
  • 5
  • 29
  • 51
abhiagNitk
  • 1,047
  • 10
  • 19
12
grecaptcha.reset(opt_widget_id)

Resets the reCAPTCHA widget. An optional widget id can be passed, otherwise the function resets the first widget created. (from Google's web page)

Kutalia
  • 519
  • 8
  • 10
  • it only reset the first captcha on the page – Maxwell s.c Jun 30 '17 at 14:40
  • @Maxwells.c Did you even read the post? Optionally you can pass an widget id and delete nth widget. If you don't pass, then the first one is reset. – Kutalia Jul 13 '17 at 09:37
  • 1
    What exactly is the widget id? I tried passing in the html id of the recaptcha
    but got an error "invalid recaptcha client id". I'm thinking I need to render the widget explicitly because I think the render() method returns the id I need.
    – Pete Oct 27 '18 at 18:30
  • opt_widget_id is optional and is the id returned from the render call, although, if missing, it will refer to the first created recaptcha widget (if you have only one widget this will suffice). – frzsombor Jul 20 '20 at 13:16
9

Or you could just simulate a click on the refresh button

// If recaptcha object exists, refresh it
    if (typeof Recaptcha != "undefined") {
      jQuery('#recaptcha_reload').click();
    }
AlxVallejo
  • 3,066
  • 6
  • 50
  • 74
  • 1
    For some reason, `Recaptcha` and `grecaptcha` are both undefined on my page. This worked for me, with a slight modification: `if( $("#recaptcha_reload").length > 0 ){ ....` – Nate-Bit Int Jan 07 '15 at 23:46
  • I used that to known when is finished the iteration of an array without count its elements. – m3nda Jan 16 '15 at 22:20
7

Try this

<script type="text/javascript" src="//www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
<script type="text/javascript">
          function showRecaptcha() {
            Recaptcha.create("YOURPUBLICKEY", 'captchadiv', {
              theme: 'red',
              callback: Recaptcha.focus_response_field
            });
          }
 </script>

<div id="captchadiv"></div>

If you calll showRecaptcha the captchadiv will be populated with a new recaptcha instance.

Tim
  • 9,351
  • 1
  • 32
  • 48
3

For AngularJS users:

$window.grecaptcha.reset();
Marcelo C.
  • 3,822
  • 2
  • 22
  • 11
1

if you are using new recaptcha 2.0 use this: for code behind:

ScriptManager.RegisterStartupScript(this, this.GetType(), "CaptchaReload", "$.getScript(\"https://www.google.com/recaptcha/api.js\", function () {});", true);

for simple javascript

<script>$.getScript(\"https://www.google.com/recaptcha/api.js\", function () {});</script>
Sara Khan
  • 325
  • 1
  • 4
  • 9
0

If you have multiple recaptcha widgets on the same page then the reset() method will default to the first, unless the widgetId is specified. The API doesn't offer a simple or reliable way to find the widget Id in code. A solution to this is to load widgets explicitly and store the widget Id in a data attribute

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

<script>
    function recaptchaLoaded() {
    
        document.querySelectorAll('.g-recaptcha').forEach((el, i) => {
            var widgetId = grecaptcha.render(el);
            el.setAttribute('data-grecaptcha-id', widgetId);
        });
    
    }

    document.getElementById("mybutton").addEventListener("click", (event) => {
        var widgetId = document.getElementById("mycaptcha").getAttribute('data-grecaptcha-id');
        grecaptcha.reset(widgetId);
    });

</script>

Note that the script URL must include render=explicit and the name of your onload callback method

Phil
  • 951
  • 12
  • 16