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

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

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

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

Аналогичный вопрос был задан о том, чтобы сделать это на странице ASP ( ссылка ), и консенсус в том, что с recaptcha было невозможно сделать это. Кажется, что несколько форм на одной странице должны делиться captcha, если вы не хотите использовать другой captcha. Если вы не заперты в recaptcha, то хорошей библиотекой, на которую нужно обратить внимание, является компонент Zend Frameworks 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() { $('.g-recaptcha').each(function(index, el) { grecaptcha.render(el, {'sitekey' : 'your_key'}); }); }; </script> 

Это легко выполнить с помощью функции clone() jQuery.

Таким образом, вы должны создать два разделителя оболочки для 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_response_field : #recaptcha_response_field и #recaptcha_challenge_field на всякий случай, если кто-то нуждается в них)

Я знаю, что этот вопрос старый, но в случае, если кто-то будет искать его в будущем. Возможно, у вас есть две надписи на одной странице. Розовый для документации находится здесь: 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> 

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

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

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

 grecaptcha.getResponse(widget_id) 

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

Я использую это определение CaptchaCallback для хранения идентификатора виджета в каждом поле 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'}); } }; 

Посмотрев исходный код страницы, я взял часть 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 и поместится в div #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> 

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

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

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

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

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

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

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

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

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

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

Вам даже не нужен прокси-сервер, потому что с перезаписыванием код 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 и вручную визуализируете каждый 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 получает идентификатор

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

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 после элемента append ) ко всем динамически модифицированным элементам. Это связывает ответ каждого отдельного captha с его формой submit .

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

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