Pergunta

Eu tenho 2 formas em uma única página. Uma das formas tem um recaptcha exibindo o tempo todo. O outro deve exibir uma recaptcha somente após um determinado evento, como estourar o limite de tentativas de login. Então, há momentos em que eu precisaria 2 ReCAPTCHA a aparecer na mesma página. Isso é possível? Eu sei que eu provavelmente poderia usar um único para ambos, mas a maneira que eu tenho o layout, eu prefiro muito mais ter 2. Graças.

Update: bem, eu acho que pode não ser possível. Alguém pode recomendar um outro biblioteca de captura de usar lado a lado com reCaptcha? Eu realmente quero ser capaz de ter 2 captchas na mesma página.

Update 2: E se colocar cada forma em um iframe? Isso seria uma solução aceitável?

Foi útil?

Solução

Uma pergunta semelhante foi perguntado sobre como fazer isso em uma página ASP ( ) eo consenso lá foi que não era possível fazer com recaptcha. Parece que múltiplas formas em uma única página devem compartilhar o captcha, a menos que você está disposto a usar um captcha diferente. Se você não é fechado em recaptcha uma biblioteca bom dar uma olhada é o componente Zend Framework Zend_Captcha ( link ). Ele contém alguns

Outras dicas

Com a versão atual do Recaptcha ( reCAPTCHA versão API 2.0 ), você pode ter vários ReCAPTCHA em uma página.

Não há necessidade de clonar o recaptcha nem tentar resolver o problema. Você apenas tem que colocar vários elementos div para os ReCAPTCHA e tornar as ReCAPTCHA dentro delas explicitamente.

Esta é fácil com a API do Google recaptcha:
https://developers.google.com/recaptcha/docs/display#explicit_render

Aqui está o código exemplo html:

<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>

Em seu código javascript, você tem que definir uma função de chamada de retorno 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>

Depois disso, o seu recaptcha url script deve ficar assim:

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

Ou em vez de dar IDs para seus campos recaptcha, você pode dar um nome de classe e laço esses elementos com o seletor de classe e .render call ()

Simples e direto:

1) Criar seus campos recaptcha normalmente com esta:

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

2) Coloque o script com o seguinte:

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

3) Agora chamar este para iterar sobre os campos e criar as ReCAPTCHA:

<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>

Isto é facilmente conseguido com a função clone() do jQuery.

Portanto, você deve criar dois divs wrapper para o recaptcha. Meu primeiro formulário recaptcha div:

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

div O segundo formulário está vazio (ID diferente). Então, o meu é apenas:

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

Então, o javascript é bastante simples:

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

Provavelmente não é necessário o segundo parâmetro com um valor true em clone(), mas não faz mal para tê-lo ... O único problema com este método é se você está enviando o formulário via ajax, o problema é que você tem dois elementos que têm o mesmo nome e você deve me um pouco mais inteligente com a maneira de capturar valores que do elemento correta (os dois ids para elementos reCaptcha são #recaptcha_response_field e #recaptcha_challenge_field apenas no caso de alguém precisa deles)

Eu sei que esta questão é antiga, mas no caso se alguém vai olhar para ele no futuro. É possível ter dois de captcha em uma página. Rosa à documentação está aqui: https://developers.google.com/recaptcha/docs/display Exemplo abaixo é apenas um doc forma de cópia e você não tem que especificar diferentes layouts.

<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>

Esta resposta é uma extensão para @raphadko 's resposta .

Se você precisa extrair manualmente o código captcha (como em Ajax pedidos) você tem que chamar:

grecaptcha.getResponse(widget_id)

Mas como você pode recuperar o parâmetro Widget id?

Eu uso essa definição de CaptchaCallback para armazenar o id Widget de cada caixa de g-recaptcha (como um atributo de dados 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);
    });
};

Então eu pode ligar no:

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

para extrair o código.

Esta é uma versão JQuery-livre da resposta dada por raphadko e substantivo .

1) Criar seus campos recaptcha normalmente com esta:

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

2) Coloque o script com o seguinte:

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

3) Agora chamar este para iterar sobre os campos e criar as ReCAPTCHA:

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'});
    }
};

Eu tenho formulário de contato no rodapé que sempre exibe e também algumas páginas, como Criar Conta, pode ter captcha também, por isso é dinamicamente e estou usando o seguinte caminho com 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>

Olhando para o código-fonte da página Tomei a parte reCaptcha e mudou o código um pouco. Aqui está o 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>

Eu estou usando aqui funcionalidade guia javascript simples. Então, não incluiu esse código.

Quando o usuário deverá clicar em "Mais Informação" (#product_tabs_what) então JS irá verificar se recapExist é false ou tem algum valor. Se ele tem um valor, então isso vai chamar Recaptcha.destroy(); destruir o velho reCaptcha carregado e irá recriá-lo para este guia. Caso contrário, isso só vai criar uma reCaptcha e irá colocar na div #more_info_recaptcha_box. Mesmo que para guia #product_tabs_wha "Faça uma oferta".

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>

Uma boa opção é gerar uma entrada recaptcha para cada formulário on the fly (Eu tenho feito isso com dois, mas você provavelmente poderia fazer três ou mais formas). Eu estou usando a validação jQuery, jQuery, e forma plugin jQuery para postar o formulário via AJAX, juntamente com a API Recaptcha AJAX -

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

Quando o usuário submete uma das formas:

  1. interceptar a apresentação - Eu usei jQuery Form Plugin beforeSubmit propriedade
  2. destruir quaisquer entradas recaptcha existentes na página - Eu costumava método e do jQuery $ .empty () Recaptcha.destroy ()
  3. chamar Recaptcha.create () para criar um campo recaptcha para a forma específica
  4. false retorno.

Em seguida, eles podem preencher o reCAPTCHA e re-enviar o formulário. Se decidir enviar um formulário diferente em vez disso, bem, seus cheques de código para ReCAPTCHA existentes de forma que você só tem uma recaptcha na página de cada vez.

Para adicionar um pouco para raphadko 's resposta : uma vez que você tem vários captchas ( em uma página), você não pode usar o) parâmetro g-recaptcha-response POST (universal (porque detém apenas a resposta de um captcha). Em vez disso, você deve usar a chamada grecaptcha.getResponse(opt_widget_id) para cada captcha. Aqui está o meu código (desde que cada captcha está dentro de sua forma):

HTML:

<form ... />

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

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

</form>

e

<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 eu aplicar a delegação de evento (consulte atualização DOM após elemento de acréscimo ) a todos os elementos modificados dinamicamente. Isso vincula a resposta de cada captha indivíduo para seu evento de forma submit.

Aqui está uma solução que constrói off muitos dos excelentes respostas. Esta opção é jQuery livre e dinâmico, e você não precisa visar especificamente elementos por id.

1) Adicionar sua marcação reCAPTCHA, como faria normalmente:

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

2) Adicione a seguinte no documento. Ele funcionará em qualquer navegador que suporta o querySelectorAll API

<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>

O método grecaptcha.getResponse() aceita um opcional "WIDGET_ID" parâmetros e padrões para o primeiro widget criado se não especificado. A WIDGET_ID é retornado do método grecaptcha.render() para cada widget criado, Não é relacionada com a id atributo do recipiente reCAPTCHA !!

Cada reCAPTCHA tem seus próprios dados de resposta. Você tem que dar o reCAPTCHA Div um ID e passá-lo para o método getResponse:

por exemplo.

<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>

resposta de acesso:

var reCaptchaResponse = grecaptcha.getResponse(0);

ou

var reCaptchaResponse = grecaptcha.getResponse(1);

É possível, basta substituir os retornos de chamada Recaptcha Ajax. jsFiddle trabalho: http://jsfiddle.net/Vanit/Qu6kn/

Você não precisa sequer de um div procuração porque com os substitui o código de DOM não serão executados. Chamada Recaptcha.reload () sempre que você deseja acionar os retornos de chamada novamente.

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");

Aqui é um bom guia para fazer exatamente isso:

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

Basicamente, você adicionar alguns parâmetros para a chamada de API e tornar 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>

PS: O método "grecaptcha.render" recebe um ID

Gostaria de usar recaptcha invisível. Em seguida, em seu uso botão uma tag como "formname = 'yourformname'" para especificar qual formulário deve ser submetido e esconder um submeter entrada de formulário.

A vantagem disso é que permite que você mantenha a validação de formulário html5 intacta, um recaptcha, mas múltiplas interfaces de botão. Apenas capturar o valor de entrada "captcha" para a chave de token gerado pelo 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>

Eu acho isso muito mais simples e mais fácil de gerir.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top