Search code examples
javascriptjqueryinvisible-recaptcha

invisible recaptcha - challenge not appearing


Implementing the Invisible reCAPTCHA on our dynamically generated forms. Our from engine gets a field list from the database, and dynamically fills the DOM with the form fields, displays it, and handles the post. To use the Invisible reCAPTCHA:

I'm loading the google api code when my page is finished loading:

<script src="https://www.google.com/recaptcha/api.js?render=explicit" async defer></script>

Once my form is loaded from the DB, I inject the recaptcha div into my field list:

form.fields.push( { html: '<div id="g-recaptcha-div" class="g-recaptcha" data-sitekey="<my site key>" data-badge="inline" data-size="invisible"></div>',
                    type: 'html'
                  } );

Later on, I append the form to the DOM (jQuery 'appendTo'), and immediately after that, I render the reCAPTCHA:

recaptcha_id = grecaptcha.render("g-recaptcha-div", 
                   { 
                     'data-callback': _settings.form.submit,
                     'sitekey'      : <my site key>
                   }, true 
                 );

and the form appears, with the reCAPTCHA badge/protected by icon showing. Looking at the DOM inspector, I can the recaptcha DIV, with the 'g-recaptcha-response' textarea there, but it's invisible. As I would expect.

Then, in my submit function, after I do some form validation, I execute the recaptcha:

grecaptcha.execute(recaptcha_id);

At which point I would expect the challenge to pop up. But it doesn't. Well, it did once. And my form submits to my PHP backend, where there is a parameter for g-recaptcha-response, but it is empty. The one time that the challenge appeared, there was a value in g-recaptcha-response.

Is the challenge always supposed to appear when the execute function is called? If not, then how should we handle the empty response value?

thanks, andy


Solution

  • Ok, for those following along at home:

    1) yes, you can specify the name of the callback function in the call to grecaptcha.render. Looking deeper, I noticed on this page (https://developers.google.com/recaptcha/docs/invisible#js_api) that I needed to specify the name of the function like so:

    recaptcha_id = grecaptcha.render("g-recaptcha-div", 
                                      { 
                                        'sitekey'  : <my site key>,
                                        'callback' : <callback>
                                      }, true 
                                    );
    

    I was trying to use "data-callback", which is how to specify it in the HTML. Doh! And to answer my other question, once you do this correctly, the callback gets called with a token whether or not the challenge is rendered.