¿Cómo muestro múltiples recaptchas en una sola página?

102

Tengo 2 formularios en una sola página. Uno de los formularios tiene un recaptcha que se muestra todo el tiempo. El otro debería mostrar un recaptcha solo después de un cierto evento, como maximizar los intentos de inicio de sesión. Entonces, hay ocasiones en las que necesito que aparezcan 2 recaptchas en la misma página. es posible? Sé que probablemente podría usar uno solo para ambos, pero por la forma en que tengo el diseño, preferiría tener 2. Gracias.

Actualización: bueno, supongo que puede que no sea posible. ¿Alguien puede recomendar otra biblioteca de captura para usar junto con reCaptcha? Realmente quiero poder tener 2 captchas en la misma página.

Actualización 2: ¿Qué pasa si colocas cada formulario en un iframe? ¿Sería esta una solución aceptable?

oym
fuente
¿No podrías mostrar el mismo dos veces?
Tyler Carter
1
Intenté eso ... cuando trato de duplicar el código captcha, solo mostrará el captcha que viene primero
oym
Cualquiera que se encuentre con esto para la nueva API de recaptcha, esto es posible mediante el uso de la carga explícita descrita con ejemplos en los documentos en developers.google.com/recaptcha/docs/display#recaptcha_methods
El Yobo
3
Un iframe debería ser posible, pero es una mala manera de resolver el problema, en comparación con el uso de JavaScript como en Hüseyin Yağlıla respuesta . La mayoría de los navegadores deberían admitir JavaScript y el reCAPTCHA predeterminado usa JavaScript de todos modos. Sin embargo, no sé qué se debería hacer para resolver el problema sin el soporte de JavaScript.
Edward

Respuestas:

14

Se hizo una pregunta similar sobre cómo hacer esto en una página ASP ( enlace ) y el consenso fue que no era posible hacerlo con recaptcha. Parece que varios formularios en una sola página deben compartir el captcha, a menos que esté dispuesto a usar un captcha diferente. Si no está encerrado en recaptcha, una buena biblioteca para echar un vistazo es el componente Zend Frameworks Zend_Captcha ( enlace ). Contiene algunos

Steven Surowiec
fuente
9
En realidad , es posible con reCAPTCHA , pero no es posible hacerlo sin JavaScript . La mayoría de los navegadores deberían admitir JavaScript y el ReCaptcha predeterminado usa JavaScript de todos modos, por lo que esta solución es buena. Hüseyin YağlıLa respuesta explica la solución. La documentación de reCAPTCHA para esta solución se encuentra en developers.google.com/recaptcha/docs/display#explicit_render . Sin embargo, no sé qué se debería hacer para resolver el problema sin el soporte de JavaScript.
Edward
Es absolutamente posible con reCAPTCHA en realidad
Carlos Espinoza
208

Con la versión actual de Recaptcha ( reCAPTCHA API versión 2.0 ), puede tener múltiples recaptchas en una página.

No es necesario clonar el recaptcha ni intentar solucionar el problema. Solo tiene que poner múltiples elementos div para las recaptchas y renderizar las recaptchas dentro de ellos explícitamente.

Esto es fácil con la api recaptcha de google:
https://developers.google.com/recaptcha/docs/display#explicit_render

Aquí está el código html de ejemplo:

<form>
    <h1>Form 1</h1>
    <div><input type="text" name="field1" placeholder="field1"></div>
    <div><input type="text" name="field2" placeholder="field2"></div>
    <div id="RecaptchaField1"></div>
    <div><input type="submit"></div>
</form>

<form>
    <h1>Form 2</h1>
    <div><input type="text" name="field3" placeholder="field3"></div>
    <div><input type="text" name="field4" placeholder="field4"></div>
    <div id="RecaptchaField2"></div>
    <div><input type="submit"></div>
</form>

En su código javascript, debe definir una función de devolución de llamada para recaptcha:

<script type="text/javascript">
    var CaptchaCallback = function() {
        grecaptcha.render('RecaptchaField1', {'sitekey' : '6Lc_your_site_key'});
        grecaptcha.render('RecaptchaField2', {'sitekey' : '6Lc_your_site_key'});
    };
</script>

Después de esto, su URL de script recaptcha debería verse así:

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

O en lugar de dar ID a sus campos de recaptcha, puede dar un nombre de clase y repetir estos elementos con su selector de clases y llamar a .render ()

Hüseyin Yağlı
fuente
1
Casualmente, ¿sabe cómo agregar un campo recaptcha oculto para la validación de jquery para cada campo ?, actualmente lo tengo trabajando solo con 1 recaptchafield pero ¿puede funcionar con dos recaptchas? <input type = "hidden" class = "hiddenRecaptcha required" name = "hiddenRecaptcha" id = "hiddenRecaptcha">
Ivan Juarez
2
@IvanJuarez Esta es una buena pregunta para hacer como una nueva pregunta.
Hüseyin Yağlı
2
Para aquellos de ustedes que quieran usar grecaptcha.getResponse () con múltiples instancias, simplemente pueden hacer referencia a cada renderizado como 0,1,2, etc. Por ejemplo, la primera instancia sería referenciada como grecaptcha.getResponse (0).
Gene Kelly
1
Ahorre mi tiempo, su solución perfecta
Mirza Obaid
2
¡Guauu! Esto requirió algo de trabajo, pero para agregar a la nota de @ GeneKelly con respecto grecaptcha.getResponse(0)y grecaptcha.getResponse(1)validar múltiples instancias, agregaría que la indexación tiene que corresponder con el grecaptcha.renderorden. Para este ejemplo, grecaptcha.render('RecaptchaField1'...se verificaría con grecaptcha.getResponse(0)y grecaptcha.render('RecaptchaField2'...se verificaría con grecaptcha.getResponse(1), etc ...
codacopia
75

Sencillo y sencillo:

1) Cree sus campos recaptcha normalmente con esto:

<div class="g-recaptcha" data-sitekey="YOUR_KEY_HERE"></div>

2) Cargue el script con esto:

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

3) Ahora llame a esto para iterar sobre los campos y crear las recaptchas:

<script type="text/javascript">
  var CaptchaCallback = function() {
    jQuery('.g-recaptcha').each(function(index, el) {
        grecaptcha.render(el, {
            'sitekey' : jQuery(el).attr('data-sitekey')
            ,'theme' : jQuery(el).attr('data-theme')
            ,'size' : jQuery(el).attr('data-size')
            ,'tabindex' : jQuery(el).attr('data-tabindex')
            ,'callback' : jQuery(el).attr('data-callback')
            ,'expired-callback' : jQuery(el).attr('data-expired-callback')
            ,'error-callback' : jQuery(el).attr('data-error-callback')
        });
    });
  };
</script>
raphadko
fuente
4
Esta es la forma correcta en mi opinión, esto lo hace dinámico porque puedo tener instancias ilimitadas sin definir identificadores estáticos
Greg Alexander
1
Si necesita extraer manualmente el código captcha (como en las solicitudes ajax), mire mi respuesta .
VanDir
¿Podría echar un vistazo a mi pregunta ? El parámetro POST está vacío.
Marcio Mazzucato
3
data-sitekey="YOUR_KEY_HERE"es inútil y se puede eliminar del div (si necesita cambiar la clave, menos lugares para editar)
the_nuts
3
De hecho, tienes un error tipográfico. El atributo data-sitekey es necesario y lo hace aún más dinámico en caso de que tenga múltiples sitekeys, ¿por qué? La línea correcta seríagrecaptcha.render(el, {'sitekey' : $(el).attr('data-sitekey') });
Gkiokan
13

Esto se logra fácilmente con la clone()función de jQuery .

Por lo tanto, debe crear dos divs de envoltura para recaptcha. Recaptcha div de mi primer formulario:

<div id="myrecap">
    <?php
        require_once('recaptchalib.php');
        $publickey = "XXXXXXXXXXX-XXXXXXXXXXX";
        echo recaptcha_get_html($publickey);
    ?>
</div>

El div del segundo formulario está vacío (ID diferente). Entonces el mío es solo:

<div id="myraterecap"></div>

Entonces el javascript es bastante simple:

$(document).ready(function() {
    // Duplicate our reCapcha 
    $('#myraterecap').html($('#myrecap').clone(true,true));
});

Probablemente no necesite el segundo parámetro con un truevalor clone(), pero no está de más tenerlo ... El único problema con este método es si envía su formulario a través de ajax, el problema es que tiene dos elementos que tienen el mismo nombre y debe ser un poco más inteligente con la forma en que captura los valores correctos del elemento (los dos identificadores para los elementos #recaptcha_response_fieldreCaptcha son y #recaptcha_challenge_field en caso de que alguien los necesite)

Serj Sagan
fuente
Encontrará problemas cuando solicite un nuevo desafío, ya que solo se actualizará una instancia de
recaptcha
esto no funciona ... significa que solo el captcha original (el primero llamado <div id = "myrecap"> aquí) solo se actualizará, y el otro no se actualizará
Oxi
En realidad, Oxi, mi comentario anterior abordó su preocupación
Serj Sagan
1
Probablemente lo esté haciendo mal ... ¿qué tal un enlace a su código en jsfiddle.net? De todos modos, ya no es necesario hacer nada de esto ... debería usar la respuesta de Hüseyin Yağlı.
Serj Sagan
7

Sé que esta pregunta es antigua, pero en caso de que alguien la busque en el futuro. Es posible tener dos captcha en una página. Rosa para la documentación está aquí: https://developers.google.com/recaptcha/docs/display El ejemplo a continuación es solo una copia del documento del formulario y no es necesario que especifique diseños diferentes.

<script type="text/javascript">
  var verifyCallback = function(response) {
    alert(response);
  };
  var widgetId1;
  var widgetId2;
  var onloadCallback = function() {
    // Renders the HTML element with id 'example1' as a reCAPTCHA widget.
    // The id of the reCAPTCHA widget is assigned to 'widgetId1'.
    widgetId1 = grecaptcha.render('example1', {
      'sitekey' : 'your_site_key',
      'theme' : 'light'
    });
    widgetId2 = grecaptcha.render(document.getElementById('example2'), {
      'sitekey' : 'your_site_key'
    });
    grecaptcha.render('example3', {
      'sitekey' : 'your_site_key',
      'callback' : verifyCallback,
      'theme' : 'dark'
    });
  };
</script>
usuario2709153
fuente
5

Esta respuesta es una extensión de la respuesta de @raphadko .

Si necesita extraer manualmente el código captcha (como en las solicitudes ajax) debe llamar a:

grecaptcha.getResponse(widget_id)

Pero, ¿cómo se puede recuperar el parámetro de identificación del widget?

Utilizo esta definición de CaptchaCallback para almacenar la identificación del widget de cada cuadro de g-recaptcha (como un atributo de datos HTML):

var CaptchaCallback = function() {
    jQuery('.g-recaptcha').each(function(index, el) {
        var widgetId = grecaptcha.render(el, {'sitekey' : 'your code'});
        jQuery(this).attr('data-widget-id', widgetId);
    });
};

Entonces puedo llamar:

grecaptcha.getResponse(jQuery('#your_recaptcha_box_id').attr('data-widget-id'));

para extraer el código.

VanDir
fuente
1
Oye, gracias por eso. ¿Qué es el #your_recaptcha_box_id?
Lucas Bustamante
4

Tengo un formulario de contacto en el pie de página que siempre se muestra y también algunas páginas, como Crear cuenta, también pueden tener captcha, por lo que es dinámico y estoy usando la siguiente forma con jQuery:

html:

<div class="g-recaptcha" id="g-recaptcha"></div>

<div class="g-recaptcha" id="g-recaptcha-footer"></div>

javascript

<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit&hl=en"></script>
<script type="text/javascript">
  var CaptchaCallback = function(){        
      $('.g-recaptcha').each(function(){
        grecaptcha.render(this,{'sitekey' : 'your_site_key'});
      })
  };
</script>
Sergey Kharchishin
fuente
4

Esta es una versión sin JQuery de la respuesta proporcionada por raphadko y sustantivo .

1) Cree sus campos recaptcha normalmente con esto:

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

2) Cargue el script con esto:

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

3) Ahora llame a esto para iterar sobre los campos y crear las recaptchas:

var CaptchaCallback = function() {
    var captchas = document.getElementsByClassName("g-recaptcha");
    for(var i = 0; i < captchas.length; i++) {
        grecaptcha.render(captchas[i], {'sitekey' : 'YOUR_KEY_HERE'});
    }
};
turboLoop
fuente
2

Mirando el código fuente de la página, tomé la parte reCaptcha y cambié un poco el código. Aquí está el código:

HTML:

<div class="tabs">
    <ul class="product-tabs">
        <li id="product_tabs_new" class="active"><a href="#">Detailed Description</a></li>
        <li id="product_tabs_what"><a href="#">Request Information</a></li>
        <li id="product_tabs_wha"><a href="#">Make Offer</a></li>
    </ul>
</div>

<div class="tab_content">
    <li class="wide">
        <div id="product_tabs_new_contents">
            <?php $_description = $this->getProduct()->getDescription(); ?>
            <?php if ($_description): ?>
                <div class="std">
                    <h2><?php echo $this->__('Details') ?></h2>
                    <?php echo $this->helper('catalog/output')->productAttribute($this->getProduct(), $_description, 'description') ?>
                </div>
            <?php endif; ?>
        </div>
    </li>

    <li class="wide">
        <label for="recaptcha">Captcha</label>
        <div id="more_info_recaptcha_box" class="input-box more_info_recaptcha_box"></div>
    </li>

    <li class="wide">
        <label for="recaptcha">Captcha</label>
        <div id="make_offer_recaptcha_box" class="input-box make_offer_recaptcha_box"></div>
    </li>
</div>

jQuery:

<script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script>
<script type="text/javascript">
    jQuery(document).ready(function() {
        var recapExist = false;
      // Create our reCaptcha as needed
        jQuery('#product_tabs_what').click(function() {
            if(recapExist == false) {
                Recaptcha.create("<?php echo $publickey; ?>", "more_info_recaptcha_box");
                recapExist = "make_offer_recaptcha_box";
            } else if(recapExist == 'more_info_recaptcha_box') {
                Recaptcha.destroy(); // Don't really need this, but it's the proper way
                Recaptcha.create("<?php echo $publickey; ?>", "more_info_recaptcha_box");
                recapExist = "make_offer_recaptcha_box";
            }
        });
        jQuery('#product_tabs_wha').click(function() {
            if(recapExist == false) {
                Recaptcha.create("<?php echo $publickey; ?>", "make_offer_recaptcha_box");
                recapExist = "more_info_recaptcha_box";
            } else if(recapExist == 'make_offer_recaptcha_box') {
                Recaptcha.destroy(); // Don't really need this, but it's the proper way (I think :)
                Recaptcha.create("<?php echo $publickey; ?>", "make_offer_recaptcha_box");
                recapExist = "more_info_recaptcha_box";
            }
        });
    });
</script>

Estoy usando aquí la funcionalidad de pestaña de JavaScript simple. Entonces, no incluyó ese código.

Cuando el usuario seleccione la opción "Solicitar información" (#product_tabs_what)a continuación, JS comprobará si recapExistes falseo tiene algún valor. Si tiene un valor, esto llamará Recaptcha.destroy();para destruir el antiguo reCaptcha cargado y lo volverá a crear para esta pestaña. De lo contrario, esto solo creará un reCaptcha y se colocará en el #more_info_recaptcha_boxdiv. Igual que para la #product_tabs_whapestaña "Hacer oferta" .

Omar Faruk Sharif
fuente
2

var ReCaptchaCallback = function() {
    	 $('.g-recaptcha').each(function(){
    		var el = $(this);
    		grecaptcha.render(el.get(0), {'sitekey' : el.data("sitekey")});
    	 });  
        };
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.google.com/recaptcha/api.js?onload=ReCaptchaCallback&render=explicit" async defer></script>


ReCaptcha 1
<div class="g-recaptcha" data-sitekey="6Lc8WQcUAAAAABQKSITdXbc6p9HISCQhZIJwm2Zw"></div>

ReCaptcha 2
<div class="g-recaptcha" data-sitekey="6Lc8WQcUAAAAABQKSITdXbc6p9HISCQhZIJwm2Zw"></div>

ReCaptcha 3
<div class="g-recaptcha" data-sitekey="6Lc8WQcUAAAAABQKSITdXbc6p9HISCQhZIJwm2Zw"></div>

surinder singh
fuente
¿Dónde están las 2 formas?
MeSo2
Lo siento, no te
entiendo
solo póngalo <div class="g-recaptcha" data-sitekey="your_site_key"></div>donde lo necesite, en formularios / divs
surinder singh
1

Una buena opción es generar una entrada recaptcha para cada formulario sobre la marcha (lo he hecho con dos, pero probablemente podrías hacer tres o más formularios). Estoy usando jQuery, jQuery validation y el complemento de formulario jQuery para publicar el formulario a través de AJAX, junto con la API Recaptcha AJAX -

https://developers.google.com/recaptcha/docs/display#recaptcha_methods

Cuando el usuario envía uno de los formularios:

  1. interceptar el envío: utilicé la propiedad beforeSubmit de jQuery Form Plugin
  2. destruir cualquier entrada recaptcha existente en la página: utilicé el método $ .empty () de jQuery y Recaptcha.destroy ()
  3. llamar a Recaptcha.create () para crear un campo recaptcha para el formulario específico
  4. falso retorno.

Luego, pueden completar el recaptcha y volver a enviar el formulario. Si deciden enviar un formulario diferente, bueno, su código verifica las recaptchas existentes, por lo que solo tendrá una recaptcha en la página a la vez.

Siliconrockstar
fuente
1

Para agregar un poco a la respuesta de raphadko : dado que tiene múltiples captchas (en una página), no puede usar el g-recaptcha-responseparámetro POST (universal) (porque solo contiene una respuesta de captcha). En su lugar, debe usar grecaptcha.getResponse(opt_widget_id)call para cada captcha. Aquí está mi código (siempre que cada captcha esté dentro de su formulario):

HTML:

<form ... />

<div id="RecaptchaField1"></div>

<div class="field">
  <input type="hidden" name="grecaptcha" id="grecaptcha" />
</div>

</form>

y

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

JavaScript:

var CaptchaCallback = function(){
    var widgetId;

    $('[id^=RecaptchaField]').each(function(index, el) {

         widgetId = grecaptcha.render(el.id, {'sitekey' : 'your_site_key'});

         $(el).closest("form").submit(function( event ) {

            this.grecaptcha.value = "{\"" + index + "\" => \"" + grecaptcha.getResponse(widgetId) + "\"}"

         });
    });
};

Observe que aplico la delegación de eventos (consulte actualizar DOM después de agregar elemento ) a todos los elementos modificados dinámicamente. Esto une la respuesta de cada captha individual a su submitevento de forma .

prograils
fuente
Vaya, estuve buscando esto durante horas. ¡¡Gracias!!
Negro
1

Aquí hay una solución que se basa en muchas de las excelentes respuestas. Esta opción es gratuita y dinámica con jQuery, por lo que no requiere que se oriente específicamente a los elementos por id.

1) Agregue su marcado reCAPTCHA como lo haría normalmente:

<div class="g-recaptcha" data-sitekey="YOUR_KEY_HERE"></div>

2) Agregue lo siguiente al documento. Funcionará en cualquier navegador que admita la API querySelectorAll

<script src="https://www.google.com/recaptcha/api.js?onload=renderRecaptchas&render=explicit" async defer></script>
<script>
    window.renderRecaptchas = function() {
        var recaptchas = document.querySelectorAll('.g-recaptcha');
        for (var i = 0; i < recaptchas.length; i++) {
            grecaptcha.render(recaptchas[i], {
                sitekey: recaptchas[i].getAttribute('data-sitekey')
            });
        }
    }
</script>
amigo
fuente
1

El grecaptcha.getResponse()método acepta un parámetro "widget_id" opcional y, por defecto, el primer widget creado si no se especifica. Se devuelve un widget_id del grecaptcha.render()método para cada widget creado, ¡ no está relacionado con el atributo iddel contenedor reCAPTCHA!

Cada reCAPTCHA tiene sus propios datos de respuesta. Tienes que darle al div reCAPTCHA un ID y pasarlo al getResponsemétodo:

p.ej

<div id="reCaptchaLogin"
     class="g-recaptcha required-entry"
     data-sitekey="<?php echo $this->helper('recaptcha')->getKey(); ?>"
     data-theme="<?php echo($this->helper('recaptcha')->getTheme()); ?>"
     style="transform:scale(0.82);-webkit-transform:scale(0.82);transform-origin:0 0;-webkit-transform-origin:0 0;">
</div>


<script type="text/javascript">
  var CaptchaCallback = function() {
    jQuery('.g-recaptcha').each(function(index, el) {
        grecaptcha.render(el, {
            'sitekey' : jQuery(el).attr('data-sitekey')
            ,'theme' : jQuery(el).attr('data-theme')
            ,'size' : jQuery(el).attr('data-size')
            ,'tabindex' : jQuery(el).attr('data-tabindex')
            ,'callback' : jQuery(el).attr('data-callback')
            ,'expired-callback' : jQuery(el).attr('data-expired-callback')
            ,'error-callback' : jQuery(el).attr('data-error-callback')
        });
    });
  };
</script>

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

Respuesta de acceso:

var reCaptchaResponse = grecaptcha.getResponse(0);

o

var reCaptchaResponse = grecaptcha.getResponse(1);
Negro
fuente
0

Es posible, simplemente sobrescriba las devoluciones de llamada de Recaptcha Ajax. Jsfiddle de trabajo: http://jsfiddle.net/Vanit/Qu6kn/

Ni siquiera necesita un div de proxy porque con las sobrescrituras el código DOM no se ejecutará. Llame a Recaptcha.reload () siempre que desee activar las devoluciones de llamada nuevamente.

function doSomething(challenge){
    $(':input[name=recaptcha_challenge_field]').val(challenge);
    $('img.recaptcha').attr('src', '//www.google.com/recaptcha/api/image?c='+challenge);
}

//Called on Recaptcha.reload()
Recaptcha.finish_reload = function(challenge,b,c){
    doSomething(challenge);
}

//Called on page load
Recaptcha.challenge_callback = function(){
    doSomething(RecaptchaState.challenge)
}

Recaptcha.create("YOUR_PUBLIC_KEY");
Vanit
fuente
0

Aquí hay una buena guía para hacer exactamente eso:

http://mycodde.blogspot.com.ar/2014/12/multiple-recaptcha-demo-same-page.html

Básicamente, agregas algunos parámetros a la llamada api y renderizas manualmente cada recaptcha:

<script src="https://www.google.com/recaptcha/api.js?onload=myCallBack&render=explicit" async defer></script>
<script>
        var recaptcha1;
        var recaptcha2;
        var myCallBack = function() {
            //Render the recaptcha1 on the element with ID "recaptcha1"
            recaptcha1 = grecaptcha.render('recaptcha1', {
                'sitekey' : '6Lc_0f4SAAAAAF9ZA', //Replace this with your Site key
                'theme' : 'light'
            });

            //Render the recaptcha2 on the element with ID "recaptcha2"
            recaptcha2 = grecaptcha.render('recaptcha2', {
                'sitekey' : '6Lc_0f4SAAAAAF9ZA', //Replace this with your Site key
                'theme' : 'dark'
            });
        };
</script>

PD: el método "grecaptcha.render" recibe un ID

Marco
fuente
0

Usaría recaptcha invisible. Luego, en su botón, use una etiqueta como "formname = 'yourformname'" para especificar qué formulario se enviará y ocultar una entrada de formulario de envío.

La ventaja de esto es que le permite mantener intacta la validación del formulario html5, una recaptcha, pero múltiples interfaces de botones. Simplemente capture el valor de entrada "captcha" para la clave de token generada por 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>

Encuentro esto MUCHO más simple y fácil de administrar.

comermeimadanish
fuente