Smartlanding

Как связать 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="6LcYtSQTAAAAAPNjrDKIiFFhwwcpaqzIkywyyZMS"></div>

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

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

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

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

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript">
$(".linkButton").click(function() {
    $( "input[name*='formInfo']" ).val($(this).attr( "title" ));
});
</script>
<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>

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

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

<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="https://smartlanding.biz">smartlanding.biz</a></p>
    </form>
  </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 '<p class="fail">Ошибка. Вы заполнили не все обязательные поля!</p>';
  } 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<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 {
  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 && $response->success) {
//отправка
else {
 echo '<p class="success">Не пройдена каптча! Попробуйте еще раз!</p>';
}

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

<?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: https://smartlanding.biz"); // главная страница вашего лендинга
}

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

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

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

Поделитесь статьей в социальных сетях, чтобы не потерять

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

  • Егор

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

    Ответить
  • dimadv7

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

    Ответить
  • Егор

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

    Ответить
  • dimadv7

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

    Ответить
  • Валерий

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

    Ответить
  • dimadv7

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

    Ответить
  • Азамат

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

    Ответить
  • Лера

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

    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 'Ошибка капчи';

    Ответить
  • Михаил

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

    Ответить
  • Anonimus

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

    Ответить
  • Лада

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

    Ответить
  • Алексей

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

    Ответить
  • Сергей

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

    Ответить
  • Сергей

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

    Ответить
  • Сергей

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

    grecaptcha.reset();
    Ответить
  • dimadv7

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

    Ответить
  • Виктор

    Прикрутил вашу форму со своими ключами к своему сайту. В аккаунте капче-гугла вверху в красной рамке такое сообщение красуется «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.»
    хотя сообщения отправляются, на почту все приходит, в форме капчи «вы не робот» подтверждается зеленой птичкой. Что это за сообщение? Так проходит все-таки проверка капчей или нет?

    Ответить
  • dimadv7

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

    Ответить
  • Виктор

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

    Ответить
  • Александр

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

    Ответить
  • Александр

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

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

    Ответить
  • Кирилл

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

    Ответить
  • dimadv7

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

    Ответить
  • Кирилл

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

    Ответить

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