Using multiple recaptcha v2 on a single page

17,448 views
Skip to first unread message

Jeremy Jarrell

unread,
Oct 8, 2014, 1:44:39 PM10/8/14
to reca...@googlegroups.com
Hello,

We are updating our recaptcha implementation to v2.  One of our target pages originally had multiple recaptcha widgets on it.  Each recaptcha was part of a div that remained hidden until displayed one at a time, similar to an accordion.

However, after upgrading to recaptcha v2 we've noticed that the recaptcha only renders on the first div it is attached to.  Subsequent divs on the page do not render the recaptcha, nor is it present in the markup.

Has anyone else experienced this and discovered a workaround?

Thanks in advance,
Jeremy

Alain Descoux

unread,
Jan 26, 2015, 4:57:00 PM1/26/15
to reca...@googlegroups.com
Yes same thing for me...

Jeremy Jarrell

unread,
Jan 26, 2015, 5:22:37 PM1/26/15
to reca...@googlegroups.com
Hi Alain,

The recaptcha team actually provided me with a solution via email.  You can accomplish this with a different API.  I'm attaching their sample file for reference to show how its done.

Good luck!
Jeremy
test.html

Alain Descoux

unread,
Jan 26, 2015, 5:44:15 PM1/26/15
to reca...@googlegroups.com
Thanks. I don't get yet the correct answer, I hope they will contact me.

Kirk Ward

unread,
Aug 11, 2017, 2:43:26 PM8/11/17
to reCAPTCHA
I added the example provided to my site and it worked for the three submit samples shown.  Perhaps those who could not get it did not add their site key?

Prathamesh Sawant

unread,
Oct 7, 2017, 12:20:47 PM10/7/17
to reCAPTCHA

Dynamically Handle Multiple Invisible reCaptcha V2 on Single Page

> Github Code: [https://github.com/prathameshsawant7/multiple-invisible-recaptcha]

> Live Example: [http://prathameshsawant.com/multiple-invisible-recaptcha/]

Step 1>
Add below 2 Js library on page


   
<!--  reCaptcha Library -->
   
<script type="text/javascript" src="https://www.google.com/recaptcha/api.js?render=explicit"></script>
   
   
<!--  Customized Init for invisible reCaptcha  -->
   
<script src="js/init_recaptcha.js" async defer></script>




Step 2>
Add below div's in respective forms.


   
<div id="recaptcha-form-1" style="display:none;"></div> <!--for Form 1-->
   
<div id="recaptcha-form-2" style="display:none;"></div> <!--for Form 2-->
   
<div id="recaptcha-form-3" style="display:none;"></div> <!--for Form 3-->





Step 3>
Create init_recaptcha.js

 * Step 1 - Initialize reCaptcha Site Key and Widget eg: widget_1 for Form 1
 * Step 2 - In init function add code to create form submit callback action.
 * Step 3 - Call renderInvisibleReCaptcha function by passing reCaptcha ID and createCallbackFn Response.



       
"use strict";
       
       
var PS = PS || {};
       
var widget_1;var widget_2;var widget_3;
       
var recaptcha_site_key = 'RECAPTCHA_SITE_KEY';
       
       
if( typeof PS.RECAPTCHA === 'undefined' ) {
           
(function (a, $) {
               
var retryTime = 300;
               
var x = {
                    init
: function(){
                       
if(typeof grecaptcha != 'undefined'){
       
                           
//For Form 1 Initialization
                           
if($('#form1 #recaptcha-form-1').length > 0){
                               
var callbackFn = {
                                    action
: function(){
                                        saveData
('1'); //Here Callback Function
                                     
}
                               
}
                               
/*--- 'recaptcha-form-1' - reCaptcha div ID | 'form1' - Form ID ---*/
                                widget_1
= x.renderInvisibleReCaptcha('recaptcha-form-1',x.createCallbackFn(widget_1,'form1',callbackFn));
                           
}
       
                                                   
//For Form 2 Initialization
                           
if($('#form2 #recaptcha-form-2').length > 0){
                               
var callbackFn = {
                                    action
: function(){
                                        saveData
('2'); //Here Callback Function
                                     
}
                               
}
                               
/*--- 'recaptcha-form-2' - reCaptcha div ID | 'form2' - Form ID ---*/
                                widget_2
= x.renderInvisibleReCaptcha('recaptcha-form-2',x.createCallbackFn(widget_2,'form2',callbackFn));
                           
}
       
                                                   
//For Form 3 Initialization
                           
if($('#form3 #recaptcha-form-3').length > 0){
                               
var callbackFn = {
                                    action
: function(){
                                        saveData
('3'); //Here Callback Function
                                     
}
                               
}
                               
/*--- 'recaptcha-form-3' - reCaptcha div ID | 'form3' - Form ID ---*/
                                widget_3
= x.renderInvisibleReCaptcha('recaptcha-form-3',x.createCallbackFn(widget_3,'form3',callbackFn));
                           
}
       
                       
}else{
                            setTimeout
(function(){ x.init();} , retryTime);
                       
}
                   
},
                    renderInvisibleReCaptcha
: function(recaptchaID,callbackFunction){
                           
return grecaptcha.render(recaptchaID, {
                                   
'sitekey'     : recaptcha_site_key,
                                   
"theme"    : "light",
                                   
'size'        : 'invisible',
                                   
'badge'    : 'inline',
                                   
'callback'     : callbackFunction
                               
});
                   
},
                    createCallbackFn
: function (widget,formID,callbackFn) {
                       
return function(token) {
                            $
('#'+formID+' .g-recaptcha-response').val(token);
                           
if($.trim(token) == ''){
                                grecaptcha
.reset(widget);
                           
}else{
                                callbackFn
.action();
                           
}
                       
}
                   
}
               
}
                a
.RECAPTCHA = x;
           
})( PS, $ );
       
}
   
        $
(window).load(function(){
            PS
.RECAPTCHA.init();
       
});




Step 4>
Changes in Form Validation JS -

  

  /* Execute respective Widget on form submit after form Validations  */
   
function formSubmit(form){
       
var text = $.trim($('#text'+form).val());
       
if(text != ''){
           
switch(form){
               
case '1' : grecaptcha.execute(widget_1); break;
               
case '2' : grecaptcha.execute(widget_2); break;
               
case '3' : grecaptcha.execute(widget_3); break;
           
}
       
}
   
}





Step 5>
Validate reCaptcha from Server Side -


   
<?php
        define
('RECAPTCHA_SECRET_KEY','KEY');
       
/**
        *  @Desc:   To Validate invisible recaptcha from server-side
        *  @Param:  g-recaptcha-response value
           *  @Return: True/False
        **/

       
if(!function_exists('check_recaptcha')){
           
function check_recaptcha($recaptcha_response){
                $test
= array ('secret' => RECAPTCHA_SECRET_KEY,'remoteip' => $_SERVER["REMOTE_ADDR"],'response' => $recaptcha_response);
               
foreach ($test as $key => $value) {
                    $req
.= $key . '=' . urlencode(stripslashes($value)) . '&';
               
}
                $req
=substr($req, 0, strlen($req)-1);
                $path
= 'https://www.google.com/recaptcha/api/siteverify?';
                $response
= file_get_contents($path . $req);
                $responseData
= json_decode($response);
               
if($responseData->success){
                   
return true;            
               
}else{
                   
return false;
               
}
           
}
       
}
       
       
// Validate reCaptcha
       
if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == "POST" && !empty($_POST)) {
            $checkCapcha
= false;
                   $recaptcha
= $_POST['g-recaptcha-response'];
                    $checkCapcha
= check_recaptcha($recaptcha);
                   
if($checkCapcha){
                        echo $_POST
['textmsg']; exit;
                       
/** Perform Actions Here (Add,Update,Delete etc)
    **/

                   
}
       
else{
                echo
reCaptcha Error”;
           
}
       
}
        echo
"failed";exit;
   
?>




Step 6>
Reset Widget after Server Call -


   
// saveData will be automatically get called on grecaptacha.execute
   
function saveData(form){
    $
.ajax( {
        type
: 'POST',
        url
:  $("#form"+form).attr( 'action' ),
        data
: $("#form"+form).serialize(),
        success
: function( response ) {
                   
switch(form){
               
case '1' : grecaptcha.reset(widget_1); break;
               
case '2' : grecaptcha.reset(widget_2); break;
               
case '3' : grecaptcha.reset(widget_3); break;
               
}
           
}
       
} );
   
}




Derek Bartron

unread,
Nov 13, 2017, 11:49:21 AM11/13/17
to reCAPTCHA
I would use invisible recaptcha.  Then on your button use a tag like " formname='yourformname' " to specify which form is to be submitted and hide a submit form input.  

The advantage of this is it allows for you to keep the html5 form validation intact, one recaptcha, but multiple button interfaces.  Just capture the "captcha" input value for the token key generated by recaptcha.

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

    <div class="g-recaptcha" data-sitekey="yours" data-callback="onSubmit" data-size="invisible"></div>

    <script>
    var formanme = ''
    $('button').on('click', function () { formname = '#'+$(this).attr('formname');
        if ( $(formname)[0].checkValidity() == true) { grecaptcha.execute(); }
        else { $(formname).find('input[type="submit"]').click() }
        });

    var onSubmit = function(token) {
        $(formname).append("<input type='hidden' name='captcha' value='"+token+"' />");
        $(formname).find('input[type="submit"]').click()
        };
    </script>

I find this FAR simpler and easier to manage.  

Денис Пчёлка

unread,
Nov 14, 2017, 1:04:01 PM11/14/17
to reCAPTCHA
в режиме инкогнито только работает

среда, 8 октября 2014 г., 20:44:39 UTC+3 пользователь Jeremy Jarrell написал:
Здравствуйте,

Мы обновляем нашу реализацию recaptcha до версии v2. На одной из наших целевых страниц изначально было несколько виджета recaptcha. Каждый recaptcha был частью div, который оставался скрытым до тех пор, пока не отобразился один за другим, подобно аккордеонам.

Однако после обновления до recaptcha v2 мы заметили, что recaptcha отображает только первый div, к которому он привязан. Последующие divs на странице не отображают recaptcha и не присутствуют в разметке.

Кто-нибудь еще испытал это и обнаружил обходной путь?

Заранее спасибо,
Джереми

Reply all
Reply to author
Forward
0 new messages