Как мне показать несколько рекапч на одной странице? - PullRequest
92 голосов
/ 07 августа 2009

У меня есть 2 формы на одной странице. Одна из форм имеет отображение все время. Другой должен отображать recaptcha только после определенного события, такого как максимальное количество попыток входа в систему. Так что бывают случаи, когда мне нужно, чтобы на одной странице появлялись 2 репатчи. Это возможно? Я знаю, что, вероятно, мог бы использовать один для обоих, но так как у меня есть макет, я бы предпочел иметь 2. Спасибо.

Обновление: ну, я думаю, это может быть невозможно. Кто-нибудь может порекомендовать другую библиотеку захвата для использования рядом с reCaptcha? Я действительно хочу иметь возможность иметь 2 капчи на одной странице.

Обновление 2: Что если поместить каждую форму в iframe? Будет ли это приемлемым решением?

Ответы [ 17 ]

1 голос
/ 08 июня 2012

Хорошим вариантом является создание ввода recaptcha для каждой формы на лету (я сделал это с двумя, но вы, вероятно, могли бы сделать три или более форм). Я использую jQuery, jQuery validation и плагин формы jQuery для публикации формы через AJAX вместе с Recaptcha AJAX API -

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

Когда пользователь отправляет одну из форм:

  1. перехватить отправку - я использовал свойство beforeSubmit плагина jQuery Form
  2. уничтожить любые существующие входные данные recaptcha на странице - я использовал метод jQuery $ .empty () и Recaptcha.destroy ()
  3. вызовите Recaptcha.create (), чтобы создать поле рекапчи для конкретной формы
  4. вернуть false.

Затем они могут заполнить резюме и повторно отправить форму. Если вместо этого они решат отправить другую форму, ваш код проверяет существующие репачи, поэтому на странице будет одновременно только одна репача.

1 голос
/ 26 января 2017

Вот решение, которое строит многие из превосходных ответов. Эта опция бесплатна и динамична в jQuery, не требуя, чтобы вы указывали элементы по идентификатору.

1) Добавьте разметку reCAPTCHA, как обычно:

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

2) Добавьте в документ следующее. Он будет работать в любом браузере, который поддерживает 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>
1 голос
/ 22 августа 2016

Чтобы добавить немного к ответу raphadko : поскольку у вас несколько капч (на одной странице), вы не можете использовать (универсальный) параметр g-recaptcha-response POST (потому что он содержит только один ответ капчи). Вместо этого вы должны использовать grecaptcha.getResponse(opt_widget_id) вызов для каждой капчи. Вот мой код (при условии, что каждая капча находится внутри своей формы):

HTML:

<form ... />

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

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

</form>

и

<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) + "\"}"

         });
    });
};

Обратите внимание, что я применяю делегирование событий (см. обновить DOM после добавления элемента ) ко всем динамически измененным элементам. Это связывает ответ каждого отдельного капфы на его событие submit.

0 голосов
/ 12 сентября 2018

Метод grecaptcha.getResponse() принимает необязательный параметр "widget_id", и по умолчанию используется первый созданный виджет, если он не указан. Widget_id возвращается из метода grecaptcha.render() для каждого созданного виджета, он не связан с атрибутом id контейнера reCAPTCHA !!

Каждый reCAPTCHA имеет свои собственные данные ответа. Вы должны присвоить reCAPTCHA div идентификатор и передать его методу getResponse:

, например

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

Ответ доступа:

var reCaptchaResponse = grecaptcha.getResponse(0);

или

var reCaptchaResponse = grecaptcha.getResponse(1);
0 голосов
/ 13 ноября 2017

Я бы использовал невидимую recaptcha. Затем нажмите кнопку «formname = 'yourformname», чтобы указать, какая форма должна быть отправлена, и скрыть ввод формы отправки.

Преимущество этого состоит в том, что он позволяет вам сохранить проверку формы html5 без изменений, одну повторную проверку, но несколько кнопок интерфейсов. Просто запишите входное значение «captcha» для ключа токена, сгенерированного 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>

Я считаю, что этот FAR проще и проще в управлении.

0 голосов
/ 04 января 2017

Вот хорошее руководство для этого:

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

По сути, вы добавляете некоторые параметры в вызов API и вручную визуализируете каждый 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: метод "grecaptcha.render" получает идентификатор

0 голосов
/ 17 февраля 2014

Это возможно, просто перезаписать обратные вызовы Recaptcha Ajax. Рабочая jsfiddle: http://jsfiddle.net/Vanit/Qu6kn/

Вам даже не нужен прокси-div, потому что с перезаписью код DOM не будет выполняться. Вызывайте Recaptcha.reload () всякий раз, когда вы хотите снова вызвать обратные вызовы.

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