Статьи и новости

Статьи и новости о веб-разработке

Несколько форм с reCAPTCHA на одной странице

Несколько форм с reCAPTCHA на одной странице

Установить несколько форм с reCAPTCHA на одной странице, при условии, что данные с форм отправляются обычным сабмитом, не составляет труда. Ведь при обычной отправке страница перезагружается и все reCaptcha обновляются вместе со страницей. Но как быть, если отправка данных осуществляется с помощью ajax? Решение есть и оно довольно простое.

Если вы уже установили reCaptcha на свой сайт, по инструкции изложенной в этой статье и внесли правки в сниппет, о которых написано здесь, то вам осталось сделать совсем немного.

Как отправлять и обрабатывать ajax данные с форм решать вам. Самый популярный способ описан здесь и мы его тоже используем.

Теперь начнем:

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

Во вторых, если форм больше одной, то потребуется обработать каждую reCAPTCHA по отдельности, для чего нам понадобятся две небольших JavaScript функции. Подробнее об этом читайте у разработчиков Google reCAPTCHA.

Итак, закрываем в сниппете комментарием эту строку:

//$script = '<script src="https://www.google.com/recaptcha/api.js?hl='.$lang.'"></script>';

В HEAD страницы сайта ставим вызов javascript reCAPTCHA:

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

Как вы заметили, после загрузки он обращается к функции onReCaptchaLoad, которую мы пропишем в самом низу страницы (можно вынести в отдельный файл со скриптами). Функция нужна для первоначального рендеринга виджетов reCAPTCHA.

Вот эта функция:


var onReCaptchaLoad = function() {
var reCaptcha;
var recaptchas = document.querySelectorAll('div[data-sitekey]');
    for (i = 0; i < recaptchas.length; i++) {
        reCaptcha = grecaptcha.render(recaptchas[i].id, {
          'sitekey' : recaptchas[i].dataset.sitekey,
        });
    }
};

Еще нам понадобится функция для сброса reCAPTCHA:


function recaptchaReload(id){
    var _recaptcha = document.getElementById(id).getElementsByTagName('form')[0].getElementsByClassName('g-recaptcha')[0];
    var _recaptcha_id = _recaptcha.getAttribute('id');
    var _sitekey = _recaptcha.getAttribute('data-sitekey');
    grecaptcha.render( _recaptcha, { sitekey : _sitekey } );
}

И, наконец, в функцию получения ajax ответа из упомянутой статьи нужно добавить вызов функции recaptchaReload с ID блока содержащего форму:


success: function(data)
{
    ...some code...
recaptchaReload('ajaxForm-1');
}

Не так уж и сложно.

Вы могли заметить, что в функции recaptchaReload используется не grecaptcha.reset, а grecaptcha.render.

Это вызвано тем, что у виджета reCAPTCHA в нашей форме, ID устанавливается динамически скриптом и меняется при получении ajax ответа.