Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add multiple invisible recaptcha in single page?

I have added two invisible recaptcha divs but when i saw the code in inspect element then only one invisible recaptcha added in my single page. My code is:

 <div id="captcha1" class="g-recaptcha"
      data-sitekey="your_site_key"
      data-callback="onSubmit"
      data-size="invisible"></div>
<div id="captcha2" class="g-recaptcha"
      data-sitekey="your_site_key"
      data-callback="onSubmit"
     ></div>

Get reference from Programmatically invoke recaptcha

Can you help me what am i doing wrong?

like image 391
Versha Gupta Avatar asked Apr 05 '17 12:04

Versha Gupta


People also ask

Can I run reCAPTCHA v2 and v3 on the same page?

Can I run reCAPTCHA v2 and v3 on the same page? To do this, load the v3 site key as documented, and then explicitly render v2 using grecaptcha.render.

How do you integrate invisible reCAPTCHA?

Invoking the reCAPTCHA verification programmatically can be achieved by rendering the challenge in a div with an attribute data-size="invisible" and programmatically calling execute. Create a div with data-size="invisible" . Call grecaptcha.execute from a javascript method. grecaptcha.execute();

Is reCAPTCHA 2 or 3 better?

Is reCAPTCHA v3 better than v2? Neither of them is good at blocking bots. While reCAPTCHA v3 is less intrusive than v2 for a user, it places a significant burden on the webmaster to determine when to let users through and when to block or challenge them. There's no right answer to this.


2 Answers

Below a more reliable solution to Peter and Alessandro answers when nesting elements.

<script>
$(".g-recaptcha").each(function() {
    var object = $(this);
    grecaptcha.render(object.attr("id"), {
        "sitekey" : "6LdwRC0UAAAAAK0hjA8O4y1tViGPk9ypXEH_LU22",
        "callback" : function(token) {
            object.parents('form').find(".g-recaptcha-response").val(token);
            object.parents('form').submit();
        }
    });
});
</script>

<form>
    <input type="text" name="example"/>
    <button id="captcha1" class="g-recaptcha">submit form 1</button>
</form>

<form>
    <input type="text" name="example"/>
    <button id="captcha2" class="g-recaptcha">submit form 2</button>
</form>

<script src='https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit' async defer></script>
like image 100
user1788978 Avatar answered Sep 19 '22 02:09

user1788978


@Prathamesh Sawant solution is complete but if you don't need this to be dynamical you can simplify the process :

1. Load recaptcha library

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

2. Add your placeholder in the HTML of each form

<form ...>
...
<div class="g-recaptcha"></div>
...
</form>

3. In your JS, write the callback you called as parameter when loading reCaptcha script :

window.onloadCallback = function() {
      $('.g-recaptcha').each(function(i, v) {
        const $placeholder = $(this)

        // Define a widget id that will be used by every grecaptcha method 
        // to keep track of which form is being used
        $placeholder.data('widget-id', i)

        grecaptcha.render( this, {
          callback: function( token ) {

            return new Promise(function(resolve, reject) {
              if( grecaptcha === undefined ) {
                console.log( 'reCaptcha not defined' )
                reject()
              }

              var response = grecaptcha.getResponse( $placeholder.data('widget-id') )
              if( !response ) {
                console.log( 'Could not get reCaptcha response' )
                reject()
              }

              const $form = $placeholder.closest('form')

              $form.find('.g-recaptcha-response').val( token )
              $form
              // Add a class that will be used to bypass the prevented submit event
              .addClass('recap-done')
              // submit by clicking the submit button of your form
              .find('[type="submit"]').trigger('click')
              resolve()
              grecaptcha.reset( $placeholder.data('widget-id') )
            })
          },
          sitekey: RECAPTCHA_KEY,
          size: 'invisible', // This makes the real reCaptcha V2 Invisible
        })
      })
    }

Note: I use a promise to prevent a Promise null issue, documented here.

4. Add a submit event handler for all forms

$('form').on('submit', function(e) {
      const $form = $(this)

      // 2nd pass (when the submit is triggered within the callback)
      // This bypasses the event to be prevented a new time -> form is really submitted
      if( $form.hasClass('recap-done') ) {
        return
      }

      // 1st pass: prevents the form to be submitted and do the reCaptcha process
      const $placeholder = $form.find('.g-recaptcha')
      if( $placeholder.length > 0 ) {
        e.preventDefault()

        grecaptcha.execute( $placeholder.data('widget-id') )
      }
    })

5. Enjoy

like image 32
ZalemCitizen Avatar answered Sep 20 '22 02:09

ZalemCitizen