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

StackOverflow https://stackoverflow.com/questions/1241947

  •  12-09-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

Другие советы

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

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

Это легко сделать с помощью 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 вам необходимо определить функцию обратного вызова для рекапчи:

<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-адрес вашего скрипта рекапчи должен выглядеть следующим образом:

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

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

Просто и понятно:

1) Создайте поля рекапчи следующим образом:

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

<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. clone() функция.

Итак, вы должны создать два div-обертки для рекапчи.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 на случай, если они кому-нибудь пригодятся)

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

<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ответ.

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

grecaptcha.getResponse(widget_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, предоставленная Рафадко и существительное.

1) Создайте поля рекапчи следующим образом:

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

2) Загрузите скрипт следующим образом:

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

3) Теперь вызовите это, чтобы перебрать поля и создать рекапчи:

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

У меня есть контактная форма в нижнем колонтитуле, которая всегда отображается, а также на некоторых страницах, таких как «Создать учетную запись», также может быть капча, поэтому она выполняется динамически, и я использую следующий способ с 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 и воссоздать ее для этой вкладки.В противном случае это просто создаст reCaptcha и будет помещено в #more_info_recaptcha_box дел.То же, что и для «Сделать предложение». #product_tabs_wha вкладка.

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>

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

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

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

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

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

Чтобы добавить немного к Рафадкоответ:поскольку у вас несколько капч (на одной странице), вы не можете использовать (универсальную) 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 событие.

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

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

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

2) Добавьте в документ следующее.Он будет работать в любом браузере, поддерживающем API запросаSelectorAll

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

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

Каждая reCAPTCHA имеет свои данные ответа.Вам необходимо присвоить элементу reCAPTCHA идентификатор и передать его в 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);

Это возможно, просто перезапишите обратные вызовы 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");

Вот хорошее руководство, как сделать именно это:

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

По сути, вы добавляете некоторые параметры к вызову API и вручную визуализируете каждую рекапчу:

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

ПС:Метод «grecaptcha.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>

Я считаю, что это НАМНОГО проще и легче в управлении.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top