Как связать reCaptcha с формой обратной связи

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

Да, есть много плагинов для CMS, но вручную сделать это немного сложнее, а раз появился такой вопрос у одного, то может и кому-то из вас пригодится статья.

Делать буду на примере свой же формы.

Форма обратной связи с recaptcha от Google

Итак, для тех, кто еще не понял, мы пытаемся добавить такую штуку в нашу форму:

recaptcha для формы обратной связи

Посмотреть пример

В первую очередь нужно получить API key для домена, на котором будет использоваться reСaptcha. Чтобы его получить, нужно перейти на эту страницу придумать названия и указать нужный домен:

recaptcha на сайт

После этого, вас перебросят на страницу, где кратко будет описана интеграция на сайт, а также находиться ваш секретный ключ и ключ сайта:

Получение секретного ключа recaptcha

Дальше, нам говорят, что перед закрывающимся тегом </head> нужно разместить следующий скрипт:

<script src='https://www.google.com/recaptcha/api.js'></script>

А в форму, там, где будет располагаться каптча - следующий блок:

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

Есть несколько дополнительных настроек, например:

  •  светлый или темный внешний вид - data-theme="light" или data-theme="dark".
  • нормальный или компактный размер - data-size="compact", data-size="norml"

Подробнее о том, какие еще есть настройки и как встроить рекаптчу в несколько форм на одной странице можно почитать тут.

Так как в моей форме все скрипты располагаются в конце страницы, то я решил и скрипт от Google поместить там же. Выглядит это все так:

<script src="modalform/libs/remodal/remodal.min.js"></script>
<script src="modalform/js/form.js"></script>
<!-- API ключ от Google -->
<script src='https://www.google.com/recaptcha/api.js'></script>
</body>
</html>

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

Разметка формы сейчас выглядит так:

<div class="remodal" data-remodal-id="firstModal" data-remodal-options="hashTracking: false,closeOnConfirm: false">
  <button data-remodal-action="close" class="remodal-close"></button>
  <div class="formArea">
    <p class="formTitle">Оставьте ваши контактные данные и наш консультант свяжется с вами</p>
    <p class="msgs"></p>
    <form id="firstForm" class="form" autocomplete="off">
      <fieldset class="form-fieldset ui-input __first">
        <input name="uname" type="text" id="username" tabindex="0" />
        <label for="username">
          <span data-text="Введите ваше имя">Введите ваше имя</span>
        </label>
      </fieldset>

      <fieldset class="form-fieldset ui-input __second">
        <input name="uemail" type="email" id="email" tabindex="0" />
        <label for="email">
          <span data-text="Введите ваш e-mail">Введите ваш e-mail</span>
        </label>
      </fieldset>

      <input name="formInfo" class="formInfo" type="hidden" value=""/>
      <!-- DIV - в котором выводится блок с recaptcha -->
      <div class="g-recaptcha" data-sitekey="6LcYtSQTAAAAAPNjrDKIiFFhwwcpaqzIkxwxxZMS" data-theme="light"></div>
      <div class="form-footer">
        <input type="submit" class="formBtn" value="Отправить заявку" />
      </div>
      <p class="formCreator"><a href="http://smartlanding.biz">smartlanding.biz</a></p>
    </form>
  </div>
</div>

Еще раз повторюсь, не обращайте внимание на форму, если не используете ту, о которой шла речь в одной из прошлых статей. Просто добавьте в нужное место своей формы div с ключом, который выдал Google.

Теперь, если попытаться получить данные переданные методом POST, мы получим не только данные из полей (имя и телефон), а и значение переменной g-recaptcha-response. Его и нужно отправить Гуглу для прохождения верификации.

Самостоятельно сделать это достаточно сложно, но есть готовый скрипт, который просто подключается к обработчику формы. Скачать его можно с Github на этой страничке:

Теперь необходимо подключить его к обработчику (php файлу, который отправляет письмо) или вставить скрипт прямо в него. У меня это файл mail.php. Подключать в самом начале:

<?php
require_once __DIR__ . '/recaptchalib.php';

if ($_SERVER["REQUEST_METHOD"] == "POST") {
  if (empty($_POST['uname']) && (empty($_POST['uemail']) || empty($_POST['uphone']))){
    echo 'Ошибка. Вы заполнили не все обязательные поля!';
  } else{
    if (isset($_POST['uname'])) {
      $uname = strip_tags($_POST['uname']);
      $unameFieldset = "<b>Имя пославшего:</b>";
    }
    if (isset($_POST['uemail'])) {
      $uemail = strip_tags($_POST['uemail']);
      $uemailFieldset = "<b>Почта:</b>";
    }
    if (isset($_POST['uphone'])) {
      $uphone = strip_tags($_POST['uphone']);
      $uphoneFieldset = "<b>Телефон:</b>";
    }
    if (isset($_POST['formInfo'])) {
      $formInfo = strip_tags($_POST['formInfo']);
      $formInfoFieldset = "<b>Тема:</b>";
    }

    $to = "dima.d.v@yandex.ru"; /*Укажите адрес, на который должно приходить письмо*/
    $sendfrom = "smart-landing@yandex.ru"; /*Укажите адрес, с которого будет приходить письмо, можно не настоящий, нужно для формирования заголовка письма*/
    $headers  = "From: " . strip_tags($sendfrom) . "\r\n";
    $headers .= "Reply-To: ". strip_tags($sendfrom) . "\r\n";
    $headers .= "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: text/html;charset=utf-8 \r\n";
    $headers .= "Content-Transfer-Encoding: 8bit \r\n";
    $subject = "$formInfo";
    $message = "$unameFieldset $uname
                $uemailFieldset $uemail
                $uphoneFieldset $uphone
                $formInfoFieldset $formInfo";

    $send = mail ($to, $subject, $message, $headers);
        if ($send == 'true') {
            echo 'Спасибо за отправку вашего сообщения!';
        } else {
          echo '<b>Ошибка. Сообщение не отправлено!</b>';
        }
  }
} else {
  header ("Location: https://smartlanding.biz"); // главная страница вашего лендинга
}

В этом файле написан код, который передаст наш секретный ключ, значение g-recaptcha-response в Google, затем произойдет проверка успешна ли пройдена каптча. Но сначала, нужно добавить несколько переменных:

// Введите свой секретный ключ
$secret = "6LcYtSQTAAAAAFcHhlqotRTiINOPlznKRfbyqmpG";
 
// пустой ответ каптчи
$response = null;

// Для проверка вашего секретного ключа
$reCaptcha = new ReCaptcha($secret);
if ($_POST["g-recaptcha-response"]) {
$response = $reCaptcha->verifyResponse(
        $_SERVER["REMOTE_ADDR"],
        $_POST["g-recaptcha-response"]
    );
}

Почти все готово, осталось добавить проверку в форму, чтобы показать пользователями, что они не заполнили каптчу. Я делаю такую:

if ($response != null &amp;amp;&amp;amp; $response->success) {
//отправка
else {
 echo 'Не пройдена каптча! Попробуйте еще раз!';
}

Полный код моего обработчика:

<?php
require_once __DIR__ . '/recaptchalib.php';
// Введите свой секретный ключ
$secret = "6LcYtSQTAAAAAFcHhlqotRTiINOPlznKRhcytynG";
// пустой ответ каптчи
$response = null;
// Проверка вашего секретного ключа
$reCaptcha = new ReCaptcha($secret);
if ($_POST["g-recaptcha-response"]) {
$response = $reCaptcha->verifyResponse(
        $_SERVER["REMOTE_ADDR"],
        $_POST["g-recaptcha-response"]
    );
}

if ($_SERVER["REQUEST_METHOD"] == "POST") {
  if (empty($_POST['uname']) && (empty($_POST['uemail']) || empty($_POST['uphone']))){
    echo '<p class="fail">Ошибка. Вы заполнили не все обязательные поля!</p>';
  } else {
    if ($response != null && $response->success) {
    if (isset($_POST['uname'])) {
      $uname = strip_tags($_POST['uname']);
      $unameFieldset = "<b>Имя пославшего:</b>";
    }
    if (isset($_POST['uemail'])) {
      $uemail = strip_tags($_POST['uemail']);
      $uemailFieldset = "<b>Почта:</b>";
    }
    if (isset($_POST['uphone'])) {
      $uphone = strip_tags($_POST['uphone']);
      $uphoneFieldset = "<b>Телефон:</b>";
    }
    if (isset($_POST['formInfo'])) {
      $formInfo = strip_tags($_POST['formInfo']);
      $formInfoFieldset = "<b>Тема:</b>";
    }

    $to = "dima.d.v@yandex.ru"; /*Укажите адрес, на который должно приходить письмо*/
    $sendfrom = "smart-landing@yandex.ru"; /*Укажите адрес, с которого будет приходить письмо, можно не настоящий, нужно для формирования заголовка письма*/
    $headers  = "From: " . strip_tags($sendfrom) . "\r\n";
    $headers .= "Reply-To: ". strip_tags($sendfrom) . "\r\n";
    $headers .= "MIME-Version: 1.0\r\n";
    $headers .= "Content-Type: text/html;charset=utf-8 \r\n";
    $headers .= "Content-Transfer-Encoding: 8bit \r\n";
    $subject = "$formInfo";
    $message = "$unameFieldset $uname<br>
                $uemailFieldset $uemail<br>
                $uphoneFieldset $uphone<br>
                $formInfoFieldset $formInfo";

    $send = mail ($to, $subject, $message, $headers);
        if ($send == 'true') {
            echo '<p class="success">Спасибо за отправку вашего сообщения!</p>';
        } else {
          echo '<p class="fail"><b>Ошибка. Сообщение не отправлено!</b></p>';
        }
    } else {
      echo '<p class="success">Не пройдена каптча! Попробуйте еще раз!</p>';
    }
  }
} else {
  header ("Location: http://smartlanding.biz"); // главная страница вашего лендинга
}

Обратите внимание на почту и не забудьте поменять на свою. Кроме того, способ подключения файла recaptchalib.php предполагает, что что mail.php и recaptchalib.php находятся рядом, то есть в одной папке. Если будет "вываливаться" ошибка, убедитесь, что пути прописаны правильно или скопируйте код прямо в обработчик (в самый верх).

Вот так, достаточно просто подключить reCaptcha для к своим формам. Надеюсь статья была полезной. Помните, что этот способ не только для той формы, о которой шла речь в начале статьи. Вы легко подключите каптчу и к любой другой. На этом - все. Пока!

Скачать исходник

Похожие публикации

52 комментария

  1. Дмитрий Давыдов

    Привет, а можешь помочь как внедрить в твою же форму эту капчу с лендингом и битриксом? https://smartlanding.biz/crm-sistema-bitrix24-dlya-landing-page.html вот в этой статье, чтобы капча была в форме тоже и обрабатывалась нормально?

    1. Дмитрий Давыдов

      Привет. Ну есть же статья о том как связать с битриксом, просто добавить код сюда.

  2. Дмитрий Давыдов

    Ммм, не нашел статью про связку с битриксом.. Куда добавить?

    1. Дмитрий Давыдов

      Вот статья о связке с битриксом.
      И вот.
      Но лучше по первой делай, там проще и понятнее.

  3. Дмитрий Давыдов

    А что в коде надо изменить, чтобы отправка происходила через движок Wirdpress? Знаю что есть плагин контакт 7 и прочие, но я думаю что данной формой будут пользоваться крайне редко, а грузить она будет всегда движок. Вот и думаю реализовать "Обратную связь" без плагинов.
    На хостинге я настроил отправку через "Яндекс для домена", потому через функцию вордпрес необходимо отправлять почту, ибо там плагин, который переводит отправку через SMTP сервера Яндекса.

    1. Дмитрий Давыдов

      Ничего практически, главное пути к файлам прописать

  4. Дмитрий Давыдов

    Сделал все как нужно. Пишет что Не пройдена каптча! Попробуйте еще раз! Целый день уже с ней мучаюсь((

    1. Дмитрий Давыдов

      Решили? У меня то же самое.

  5. Дмитрий Давыдов

    А почему нельзя использовать самую простую конструкцию, типа:

    function check_captcha($secret, $response){
    $result_capcha = json_decode(file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$response));

    if (isset ($result_capcha->success) && $result_capcha->success != 1)
    return false;
    else
    return true;
    }
    и потом:
    $secret = '6LfZCgQTAABAAMRHnFbMydXчегототамещё';
    $response = $_POST['g-recaptcha-response'];

    if(check_captcha($secret, $response))
    echo 'Всё ок';
    else
    echo 'Ошибка капчи';

  6. Дмитрий Давыдов

    Вроде все рассказано. Спасибо. Только у меня 4 (четыре) файла mail.php в разных папках. Какой из них является обработчиком, как узнать?

    1. Дмитрий Давыдов

      Возможно каждый из них для разных форм/страниц сайта.

  7. Дмитрий Давыдов

    Спасибо большое! Очень-очень пригодилась информация :-)

  8. Дмитрий Давыдов

    А как добавить в этот обработки загрузку файлов? Можете подсказать?

  9. Дмитрий Давыдов

    Всё замечательно, но вот если в первый раз что то забыл дописать или например с ящиком ошибся вовремя отправки, то приходится перезагружать страницу, т.к. капча вроде как и проверена (зеленая галочка) но по факту после второй отправки ошибка проверки капчи.
    нужно сделать чтобы капча сбрасывалась после отправки.
    И это кстати у вас в примере.

  10. Дмитрий Давыдов

    Как оказалось лечится просто

    grecaptcha.reset();
    1. Дмитрий Давыдов

      Спасибо, что отписались)

    2. Дмитрий Давыдов

      Как оказалось лечится просто
      grecaptcha.reset();

      А куда это подставлять?

  11. Дмитрий Давыдов

    Прикрутил вашу форму со своими ключами к своему сайту. В аккаунте капче-гугла вверху в красной рамке такое сообщение красуется "We detected that your site is not verifying reCAPTCHA solutions. This is required for the proper use of reCAPTCHA on your site. Please see our developer site for more information."
    хотя сообщения отправляются, на почту все приходит, в форме капчи "вы не робот" подтверждается зеленой птичкой. Что это за сообщение? Так проходит все-таки проверка капчей или нет?

    1. Дмитрий Давыдов

      Не знаю, не сталкивался с такой ошибкой. А проверить можно не заполняя каптчу, если отправится - значит не работает... Но никаких сообщений, лишних, быть не должно.

  12. Дмитрий Давыдов

    Если не заполнить капчу - сообщение не отправляется. В вашем варианте пишет "Не пройдена капча. Попробуйте еще раз". Если заполнить - то все работает штатно. Но предупреждение в гугл аккаунте все равно присутствует. Можно ли как-то еще узнать, проходит ли проверка? Или эта капча просто как ничего не значащий чек-бокс?

  13. Дмитрий Давыдов

    Привет!
    Как привязать капчу к форме, которая отправляет данные в телеграм? ( из этой статьи https://smartlanding.biz/otpravka-dannyx-formy-v-telegram.html)

  14. Дмитрий Давыдов

    Здравствуйте а подскажите пожалуйста как к этой форме прикрутить отправку файлов во вложении?

    1. Дмитрий Давыдов

      В данном случае - никак. Другой подход нужен. Не через serialize, а через FormData.

  15. Дмитрий Давыдов

    dimadv7 спасибо я принципе разобрался только такой вопрос при нажатии на кнопку отправить сообщение ничего происходит, изначально всё отправляла форма через день перестала, посмотрел лог ошибок не видит send.php пишет типа php.sock в чём проблема может быть? получается что нет связи между js и php от тупо не отправляет данные в обработчик чтобы отправить письмо!

  16. Дмитрий Давыдов

    Помогите, сделал всё как у вас но пишет ОШИБКА: неверный домен ключа

    1. Дмитрий Давыдов

      Ошибка возникает когда используете ключи не зарегистрированные для конкретного домена.

  17. Дмитрий Давыдов

    Добрый день. Уточните у меня выскакивает ошибка php Fatal error: Class 'ReCaptcha' not found . Я так понял, что движок Php на сайте слишком старый для этого когда?? (WordPress 3.1.4) Или еще в чем проблема ?

    1. Дмитрий Давыдов

      Мiki, Php версия 5.5.15

    2. Дмитрий Давыдов

      Здравствуйте, похоже, что просто файл не подключен. Проверьте все пути еще раз. Особенно тут: require_once __DIR__ . '/recaptchalib.php';

      А насчет версии PHP, я только в 5.6 и 7.1 тестировал.

  18. Дмитрий Давыдов

    Пишет, что не пройдена каптча, где может быть загвоздка?

  19. Дмитрий Давыдов

    Большое спасибо, Дмитрий!
    А не подскажите, всплывающая подсказка с восклицательным знаком на оранжевом фоне и текст: "Адрес электронной почты должен одержать символ "@" " при нажатии на кнопку "Отправить заявку" она втроена в браузер? я не могу найти её ни в консоли, ни в стилях, ни в php

    1. Дмитрий Давыдов

      type="email" - Вот что проверяло на валидность электронный адрес. Не зря говорят, что утро вечера мудреннее.
      Удобная эта встроенная валидация, главное, что теперь известно, как её добавить/убрать.
      Ещё раз спасибо за форму. В сети много хороших уроков по созданию форм, по валидации, но нигде нет одновременной привязки капчи и формы без перезагрузки с аяксом. Это такой головняк! Редко такие спецы встречаются, чтобы при этом делились знаниями в довольно доходчивой форме.

    2. Дмитрий Давыдов

      Настя, спасибо. Здорово что разобрались. Да атрибут значение в атрибуте type влияют на стандартное поведение и реакцию браузера. То есть то, как он реагирует на конкретное поле. Вот тут о них подробнее

  20. Дмитрий Давыдов

    Мне помогло это:

    $(document).ready(function(){
            $('.formBtn').click(function(){
        grecaptcha.reset();
    });
    });
    

    где .formBtn - класс кнопки, которая отправляет сообщение. Ну вы видели её в разметке.
    А вот как сделать так, чтобы данные полей не удалялись после появления сообщения об ошибке?

    1. Дмитрий Давыдов

      Настя, попробуйте очищать поля не по success, а при complete. Это в ajax запросе в файле form.js. Ведь success - это просто успешный ответ сервера, но это не значит, что форма успешно ушла. Если на стороне сервера, например, форма не прошла валидация то в success выводится ошибка и поля очищаются. Делайте это при complete.

    2. Дмитрий Давыдов

      dimadv7, Вот эта строка? я её закомментировала для обоих вариантов ( success и error), а complete я не нашла.
      $('input').not(':input[type=submit], :input[type=hidden]').val('');
      И вроде работает

      А вот эта конструкция, которую я описала в предыдущем сообщении, вредная:
      $(document).ready(function(){
      $('.formBtn').click(function(){
      grecaptcha.reset();
      });
      });
      Капча как бы обновляется, но даже при прохождении скрипт считает её не пройденной и выдаёт соответствующее сообщение об ошибке

    3. Дмитрий Давыдов

      Настя, complete и нет в исходнике. Нужно самой дописывать. Но предварительно нужно загуглить про ajax jquery и разобраться со всем. Там будет описанные все доступные события и методы

    4. Дмитрий Давыдов

      dimadv7, Большое спасибо за наводку! Работает! Сделала событие complete сразу после события error, это помогло для капчи
      },
      complete: function(){
      grecaptcha.reset();
      } ...
      но не помогло для сброса содержимого полей. Они очищались и при ошибке, и при не введённой капче. Вставила рядом с echo с сообщением об успешной отправке данных очищение формы в php, а из js их убрала:
      ...if ($send == 'true') {
      echo 'Спасибо за отправку вашего сообщения!';
      ?>
      $('.reset').val('');
      <?php
      } else {....
      класс reset добавила каждому полю ввода

  21. Дмитрий Давыдов

    лять!
    как не крутил, не вертел, alert не могу сделать об успешной отправке(

    1. Дмитрий Давыдов

      Евген, привет. Давай попробую помочь. Как делаешь-то? Какие ошибки появляются? Как пытался решить?

  22. Дмитрий Давыдов

    При создание ключа и выборе рекапчи V2, есть выбор "Невидимый значок рекапча", можно его выбрать и следовать инструкции в этой статье, всё ли будет работать? или выбирать Флажок "Я не робот"?

    1. Дмитрий Давыдов

      Максим, с остальными видами reCaptcha пока не разбирался. Не было необходимости и подходящего случая.

  23. Дмитрий Давыдов

    Или рекапчу V3 использовать по этой инструкции можно?

  24. Дмитрий Давыдов

    Скачал ваше демо ,заменил ключи ,настроил пути , поставил свою почту , но сообщения до сих пор нету

    1. Дмитрий Давыдов

      Матвей, здравствуйте. Осталось проверить ошибки в консоли, и ввести ошибки php и проверить нет ли их. Затем убедиться, что php > 7 версии. Убедиться, что не используете бесплатный домен. У хостинга не тестовый период, а оплаченный. Хостер позволяет отправлять письма на бесплатные почтовые сервисы почту, а не только на привязанные к домену.

  25. Дмитрий Давыдов

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

    1. Дмитрий Давыдов

      Алексей, привет. Попробуй указать в форме method="POST", и перевести сайт на https, то есть все подключаемые скрипты тоже должны быть по протоколу https, у тебя в разнобой.

    2. Дмитрий Давыдов

      dimadv7, спасибо) На самом деле все было намного проще так сказать, дело было не в бабине долба*б сидел в кабине, скрипты не подключились которые в подвал загнал

    3. Дмитрий Давыдов

      Алексей, ну бывает у всех))) Хорошо, что разобрался)

  26. Дмитрий Давыдов

    dimadv7, Привет а не подскажешь как заставить работать две формы на странице. Скрипт считывает ту что снизу сайта но сверху по коду а при заполнении popup выдает ошибку не все заполнены

    1. Дмитрий Давыдов

      Алексей, у форм должен быть разный id.

  27. Дмитрий Давыдов

    Алексей, И снова все оказалось просто)
    Если у кого-то не будут работать две формы то делаем простую замену в строке

    на secondForm ну или других ID

Добавить комментарий

 

© 2014 — 2020, Smartlanding.biz. Все права защищены. Любое использование материалов допускается только с указанием активной ссылки на источник. Политика конфиденциальности