Как показать несколько рекапчей на одной странице?


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

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

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

17 87

17 ответов:

аналогичный вопрос был задан об этом на странице ASP (ссылке) и консенсус там был, что это не было возможно сделать с recaptcha. Кажется, что несколько форм на одной странице должны совместно использовать капчу, если вы не хотите использовать другую капчу. Если вы не заблокированы в recaptcha хорошая библиотека, чтобы взглянуть на это Zend Framework zend_captcha компонент (ссылке). Он содержит несколько

С текущей версией Recaptcha (reCAPTCHA API версии 2.0), вы можете иметь несколько recaptchas на одной странице.

нет необходимости клонировать recaptcha или пытаться обойти проблему. Вам просто нужно поместить несколько элементов div для recaptchas и явно отобразить recaptchas внутри них.

Это легко с Google recaptcha api:
https://developers.google.com/recaptcha/docs/display#explicit_render

вот пример 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>

в коде javascript, вы должны определить функцию обратного вызова для 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>

после этого url-адрес вашего сценария recaptcha должен выглядеть так:

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

или вместо того, чтобы давать идентификаторы вашим полям recaptcha, вы можете дать имя класса и зациклить эти элементы с помощью селектора классов и вызов.render ()

простой и понятный:

1) Создайте свои поля recaptcha обычно с этим:

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

2) загрузите скрипт с этим:

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

3) Теперь вызовите это, чтобы перебрать поля и создать 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>

это легко сделать с помощью jQuery в .

таким образом, вы должны создать две обертки divs для recaptcha. Моя первая форма recaptcha div:

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

div второй формы пуст (другой идентификатор). Так что мой просто:

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

тогда javascript довольно прост:

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

наверное, не нужен второй параметр true значение clone(), но не больно, чтобы иметь его... Единственная проблема с этим методом является если вы отправляете свою форму через ajax, проблема в том, что у вас есть два элемента с одинаковым именем, и вы должны быть немного умнее с тем, как вы фиксируете значения этого правильного элемента (два идентификатора для элементов reCaptcha -#recaptcha_response_field и #recaptcha_challenge_field на всякий случай, если кто-то нуждается в них)

Я знаю, что этот вопрос старый, но в случае, если кто-то будет искать его в будущем. Можно иметь две капчи на одной странице. Розовый к документации здесь:https://developers.google.com/recaptcha/docs/display Пример ниже - это просто копия формы doc, и вам не нужно указывать разные макеты.

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

этот ответ является продолжением @raphadkoответом.

Если вам нужно вручную извлечь код captcha (например, в ajax-запросах), вам нужно позвонить:

grecaptcha.getResponse(widget_id)

но как вы можете получить параметр id виджета?

Я использую это определение CaptchaCallback для хранения виджет id каждого поля G-recaptcha (как атрибут данных 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);
    });
};

Затем Я можно позвонить:

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

для извлечения кода.

это JQuery-бесплатная версия ответа, предоставленного raphadko и существительное.

1) Создайте свои поля recaptcha обычно с этим:

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

2) загрузите скрипт с этим:

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

3) Теперь вызовите это, чтобы перебрать поля и создать 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'});
    }
};

у меня есть контактная форма в нижнем колонтитуле, которая всегда отображается, а также некоторые страницы, такие как Create Account, также могут иметь captcha, поэтому это динамически, и я использую следующий способ с 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>

глядя на исходный код страницы, я взял часть reCaptcha и немного изменил код. Вот код:

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>

я использую здесь простую функциональность вкладки javascript. Итак, не включил этот код.

когда пользователь нажмет на кнопку "Запросить информацию"(#product_tabs_what) тогда JS проверит, если recapExist - это false или имеет какое-то значение. Если он имеет значение, то это вызовет Recaptcha.destroy(); чтобы уничтожить старый загруженный reCaptcha и воссоздать его для этой вкладки. В противном случае это просто создаст рекапчу и поместит в #more_info_recaptcha_box div. То же самое, что и для "сделать предложение" #product_tabs_wha tab.

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>

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

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

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

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

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

добавить немного raphadkoответом: так как у вас есть несколько капчи (на одной странице), вы не можете использовать (универсальный) g-recaptcha-response параметр POST (потому что он содержит только один ответ captcha). Вместо этого, вы должны использовать 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 после добавления элемента) для всех динамически изменяемых элементов. Это связывает ответ каждого отдельного captha к своей форме submit событие.

вот решение, которое строит из многих отличных ответов. Этот параметр является свободным от 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>

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

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

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

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

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: "грекапча.метод render" получит код

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

преимущество этого заключается в том, что вы можете сохранить проверку формы html5 неповрежденной, одну рекапчу, но несколько интерфейсов кнопок. Просто захватить "капча" введите значение ключа генерируется капча.

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

Я считаю, что это гораздо проще и легче управлять.

The grecaptcha.getResponse() метод принимает необязательный параметр "widget_id" и по умолчанию используется первый виджет, созданный, если он не указан. Widget_id возвращается из grecaptcha.render() метод для каждого виджета, созданного, это не связано с атрибутом id из контейнера 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);