Множетственная ReCaptcha2 на 1 стр + Ajaxform

Добрый день! Вдохновленный заметкой и комментарием Андрея в ней, я решил немного по подробнее расписать про особенности подключения Google ReCaptcha 2 для использования в MODX Revolution c дополнением AjaxForm и FormIt.


Под катом пример с картинками.

Итак, стояла задача установить Google ReCaptcha2 в трех формах на одной странице (Лэндинг). Две из которых запрос прайса на почту и одна с просьбой перезвонить.

Работает все изначально через AjaxForm в связке с FormIt. Для этого ставим компонент recaptchav2, в настройках через системные параметры MODX задаем sitekey и secretkey, предварительно получив их тут.

Первый шаг: тут логинимся в google и задаем имя набора параметров и домен сайта где будет каптча:

Второй шаг: тут получаем заветные ключи и копируем себе, их мы и будем указывать в параметрах MODX:

Третий шаг: полученные ключи мы прописываем в соответствующих настройках MODX как показано на скриншоте.

Четвертый шаг: Необходимо поработать с кодом шаблона ресурса, на котором предполагается использовать несколько вызовов ReCaptcha2. Следующим образом. В подвал добавляем вызов апи Google и небольшой javascript который будет отвечать за рендер каптчи, т.к. штатные вызовы компонента recaptchav2 в данной ситуации не подходят, ниже код:
<script src="https://www.google.com/recaptcha/api.js?onload=MyCallBack&render=explicit" async defer></script>
        <script>
          var recaptcha1;
          var recaptcha2;
          var recaptcha3;
          var MyCallBack = function() {
            //Render the recaptcha1 on the element with ID "recaptcha1"
            recaptcha1 = grecaptcha.render('recaptcha1', {
              'sitekey' : '[[++recaptchav2.site_key]]', //Replace this with your Site key
              'theme' : 'light'
            });
            
            //Render the recaptcha2 on the element with ID "recaptcha2"
            recaptcha2 = grecaptcha.render('recaptcha2', {
              'sitekey' : '[[++recaptchav2.site_key]]', //Replace this with your Site key
              'theme' : 'dark'
            });
            //Render the recaptcha3 on the element with ID "recaptcha3"
            recaptcha3 = grecaptcha.render('recaptcha3', {
              'sitekey' : '[[++recaptchav2.site_key]]', //Replace this with your Site key
              'theme' : 'light'
            });
          };
        </script>
Небольшое пояснение:
1) к апи идет обращение с параметром MyCallBack он может быть абсолютно любым, далее по коду есть одноименная переменная которой присваивается функция.
2) в функции задаем переменную recaptcha1 и в ней одноименный параметр, это будет id div а в который будет выводится каптча, как называть — ваше дело. Делаем по аналогии для всех трех каптч.
3) далее в sitekey не забываем поставить плейсхолдер системного параметра компонента recaptchav2 и можно пожеланию выбрать тему в параметре theme светлую или темную.

Пятый шаг: Нужно привести вызов сниппета AjaxForm к следующему примерно виду:
[[!AjaxForm?
    &snippet=`FormIt`
    &form=`form.request`
    &hooks=`recaptchav2,email`
    &emailFrom=`[[++mail_smtp_user]]`
    &emailFromName=`Админ сайта`
  	&emailSubject=`Запрос прайса с сайта [[++site_url:replace=`http://== `:replace=`/== `]]`
  	&emailTo=`yourmail@domain.tld`
  	&emailTpl=`tpl.mail.price`
  	&frontend_js=`[[+assetsUrl]]js/custom.js`
    &validate=`name:required,emailclient:email:required,g-recaptcha-response:required`
    &validationErrorMessage=`В форме содержатся ошибки!`
    &successMessage=`Заявка успешно отправлена`
    &name.vTextRequired=`Пожалуйста, укажите, как к вам обращаться`
    &email.vTextRequired=`Пожалуйста, укажите свою электронную почту`
]]
В хуке обязательно указать recaptchav2
а в чанке form.request, в конце формы, перед кнопкой отправки формы добавить див для рендера каптчи:
<div class="form-item">
              <div id="recaptcha1"></div>
              <span class="error_g-recaptcha-response error"></span>
            </div>
И по аналогии в чанках других форм сделать с разницей только лишь в id diva которые мы указали в javascript коде под вызовом api google.
Ниже дива идет span для отработки ошибок ввода каптчи.

Как результат получаем вот что:


При такой конфигурации все должно работать.
Sergey Leleko
17 мая 2017, 11:11
modx.pro
34
4 606
+13

Комментарии: 21

Scorp Satex
17 мая 2017, 19:39
+1
Спасибо, буквально недавно столкнулся с этой задачей. Буду пробовать.
Павел
23 мая 2017, 13:43
+3
Небольшая пометка. Чтобы высвечивалось необходимость заполнения рекапчи (проверку на галку), т.е. «Это поле обязательно для заполнения.» Нужно в вызов Ajaxform добавить:
&validate=`g-recaptcha-response:required`
    Sergey Leleko
    24 мая 2017, 06:34
    +1
    Абсолютно верное замечание, спасибо! Я внес правку в код вызова
Alex Lenk
25 мая 2017, 23:10
0
Подскажите пожалуйста, от чего данная ошибка происходит? это в консоле браузера на сайте
Uncaught Error: ReCAPTCHA placeholder element must be an element or id
    at Object.Yp [as render] (recaptcha__ru.js:470)
    at MyCallBack (common.js:25)
    at c (recaptcha__ru.js:465)
Yp @ recaptcha__ru.js:470
MyCallBack @ common.js:25
c @ recaptcha__ru.js:465
    Sergey Leleko
    26 мая 2017, 07:05
    0
    Добрый день!
    А делали точно все по этой статье? используется точно компонент recaptchav2 и хук указан от него?
    просто первую версию рекаптчи гугл вроде как вообще более не поддерживает…
      Alex Lenk
      26 мая 2017, 07:39
      0
      да, а можете показать чанк form.request возможно я там ошибку допустил:
      [[!AjaxForm?
          &snippet=`FormIt`
          &form=`form.callWizard`
          &hooks=`recaptchav2,email`
          &emailFrom=`[[++mail_smtp_user]]`
          &emailFromName=`Админ сайта [[++site_url:replace=`http://== `:replace=`/== `]]`
        	&emailSubject=`Вызов замерщика с сайта [[++site_url:replace=`http://== `:replace=`/== `]]`
        	&emailTo=`artlenk.ru@gmail.com`
        	&emailTpl=`tpl.callWizard`
          &validate=`name:required,phone:required,g-recaptcha-response:required`
          &validationErrorMessage=`В форме содержатся ошибки!`
          &successMessage=`Заявка успешно отправлена`
          &successMessage=`<h3>Ваше заявка отправлена</h3><p style="width: 319px;">Наши специалисты свяжутся с вами в ближайшее время.</p>
      
      `
          &name.vTextRequired=`Пожалуйста, укажите, как к вам обращаться`
          &phone.vTextRequired=`Пожалуйста, укажите свой номер телефона`
      ]]
        Sergey Leleko
        26 мая 2017, 07:44
        0
        да, у меня он такой:
        <form action="" method="post" class="ajax_form form text-top">
         <div class="fields incon">
            <div class="incon" style="width: auto;">
               <div class="field" data-type="name">
                  <div class="name">
                     <div class="">Имя</div>
                  </div>
                  <div class="input"> <input type="text" name="name" class="form-control" style="border-radius: 4px;"> <span class="error_name"></span>  </div>
               </div>
            </div>
            <div class="incon" style="width: auto;">
               <div class="field" data-type="phone">
                  <div class="name">
                     <div class=""> E-mail<span class="required">*</span> </div>
                  </div>
                  <div class="input"> <input type="text" name="emailclient" class="form-control" style="border-radius: 4px;"> <span class="error_email"></span> </div>
               </div>
            </div>
            <div class="incon">
                    <div class="form-item">
                      <div id="recaptcha1"></div>
                      <span class="error_g-recaptcha-response error"></span>
                    </div>
            </div>
         </div>
         <div class="macros-button">
            <div class="btnwrap">
               <div class="incon"> <input data-action="" type="submit" class="btn"> </div>
            </div>
         </div>
        </form>
        Sergey Leleko
        26 мая 2017, 07:45
        0
        smtp у вас точно настроен в системных параметрах?
          Alex Lenk
          26 мая 2017, 14:12
          0
          нет, у меня там ничего не прописано было. Я убрать пару строк и все заработало
          &emailFrom=`[[++mail_smtp_user]]`
          	&emailFromName=`Админ сайта`
          	&frontend_js=`[[+assetsUrl]]js/custom.js`
            Sergey Leleko
            26 мая 2017, 19:39
            0
            &frontend_js=`[[+assetsUrl]]js/custom.js`
            еще этого файла у вас конечно же нету, прописывая этот параметр подразумевал модифицированный стандартный js Ajaxform а
Константин Ильин
08 июня 2017, 17:33
1
+3
Немного проще делается с капчей, ведь реально неудобно когда много форм и каждую надо в переменную забивать — это неудобно. Лучше использовать each для прохода.

Скрипты
<script src="https://www.google.com/recaptcha/api.js?onload=CaptchaCallback&render=explicit" async defer></script>
<script>
var CaptchaCallback = function() {
    $('.g-recaptcha').each(function(index, el) {
        grecaptcha.render(el, {'sitekey' : '[[++recaptchav2.site_key]]'});
    });
};
</script>
Разметка в любой форме одинаковая
<form>
.....
 <div class="g-recaptcha" data-sitekey="[[++recaptchav2.site_key]]"></div>
.....
</form>
    Sergey Leleko
    08 июня 2017, 21:07
    0
    Хорошее решение. Не против если его в текст статьи добавлю?

    PS видимо недостаточны мои знания JS)
Александр Мельник
08 июня 2017, 22:53
0
Использовал такой же подход, он не единажды описан на просторах интернета.
А вот кто-то пробовал работать с новой невидимой каптчей гугла?
Есть опыт относительно MODX, AjaxForm и FormIt?

    Viktor
    20 февраля 2018, 20:32
    1
    +2
    Я сделал решение и даже пошаговою инструкцию уже написал, но не хватает рейтинга чтобы запостить. Демо: http://s6728.h5.modhost.pro/
      Роман Ильин
      20 февраля 2018, 21:24
      0
      Приложился к рейтингу, чтоб вы могли сделать публикацию
      Роман Ильин
      20 февраля 2018, 21:25
      0
      Как я понял, вы сделали client-side вариацию этой рекапчи?
        Viktor
        20 февраля 2018, 21:36
        +1
        Не совсем понял о чем вы. Валидация на стороне сервера тоже есть за счет хука, при отключенном js форма не отправится.
          Роман Ильин
          20 февраля 2018, 21:46
          0
          Есть два варианта реализации рекапчи:
          1. Клиент-сайд – валидация капчи происходит чисто средствами JS, без участия сервера.
          2. Сервер-сайд – валидация капчи происходит на сервере. В случае с modx – хуком в formit.

          Мне показалось у вас 1 вариант.
            Viktor
            20 февраля 2018, 21:58
            0
            Валидация есть на стороне клиента и сервера. В моем варианте при отключенном js форма не отправиться. Здесь есть реализация через iframe, но стоит ли заморачиваться?
          Роман Ильин
          20 февраля 2018, 21:50
          0
          var CaptchaCallback = function() {
                  $(recaptchas).each(function(i, el) {
                      grecaptcha.render(el, {
                          'sitekey' : '6LeGKkcUAAAAAF8JYitV9RlNWPy_11hFFvyjktFO',
                          'size' : 'invisible',
                          'badge' : 'inline',
                          'callback' : function() {
                              afValidated = true;
                              $(el).closest('form').submit();
                          }
                      });
                  });
              };
          на эту мысль натолкнул вот этот ваш код и документация по рекапче:
          developers.google.com/recaptcha/docs/invisible#example
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
21