ФорумПрограммированиеПыхнуть хотите?F.A.Q. → FAQ: PHP + JQuery UI + ReCaptcha (всплывающая recaptcha и ajax)

FAQ: PHP + JQuery UI + ReCaptcha (всплывающая recaptcha и ajax)

  • Ivan

    Сообщения: 1316 Репутация: N Группа: Адекваты

    Spritz 19 сентября 2011 г. 15:22, спустя 12 минут 30 секунд

    Статья для тех у кого возникло желание быстро и красиво прикрутить всплывающую капчу себе на сайт. Тонкости JQuery UI тут описывать не буду - приведу лишь примеры кода.



    Что нужно?
    1. JQuery UI
    2. ReCaptcha Public и Private Keys
    3. ReCaptcha PHP Library

    Создаем файл настроек settings.php
    <?php

    return array(
       'public_key' => 'тут ваш паблик ключ',
       'private_key' => 'тут приватный ключ',
    );


    Создаем страницу getkey.php (не обязательно - можете передать ключ напрямую, но в таком случае у вас будет возможность как-то обозначить что пользователь сейчас запросил капчу)
    <?php
    session_start();
    $recaptcha_cfg = require 'settings.php';
    echo $recaptcha_cfg['public_key'];


    Создаем страницу verify.php - на ней мы будем вызывать проверку вводил ли пользователь капчу уже или нет
    <?php
    session_start();
    echo isset($_SESSION['nobot']) ? 'yes' : 'no';


    Создаем страницу check.php - через неё мы будем проверять капчу и устанавливать что пользователь человек
    <?php
    session_start();
    require_once 'recaptchalib.php';
    $recaptcha_cfg = require 'settings.php';
    if (( !isset($_SESSION['nobot']) ) and ( isset($_POST['recaptcha_response_field']) )) {
       $resp = recaptcha_check_answer
       (
           $recaptcha_cfg['private_key'], $_SERVER['REMOTE_ADDR'],
           $_POST['recaptcha_challenge_field'], $_POST['recaptcha_response_field']
       );
       if ($resp->is_valid) {
           $_SESSION['nobot'] = true;
           echo 'success';
       } else {
           echo 'fail';
       }
    } elseif (!isset($_POST['recaptcha_response_field'])) {
    echo 'fail';
    } else {
       echo 'success';
    }


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

    Далее выносим JS-логику в отдельный скрипт client.js:
    $(document).ready(function() {
       $("#dialog-ui").dialog({
               resizable: false,
               width: 460,
               modal: true,
               autoOpen: false,
               buttons: {
                   'Проверить введенный код': function() {
                       challengeField = $("#recaptcha_challenge_field").val();
                       responseField = $("#recaptcha_response_field").val();
                       $(this).dialog('option', 'title', 'Подождите идёт проверка…');
                       var html = $.ajax({
                           type: "POST",
                           url: "/check.php",
                           data: "recaptcha_challenge_field=" + challengeField + "&recaptcha_response_field=" + responseField,
                           async: false
                       }).responseText;
                       if (html.replace(/^\s+|\s+$/, '') == "success") {
                           $(this).dialog("close");
                       } else {
                           $(this).dialog('option', 'title', 'Ошиблись - попробуйте снова');
                           Recaptcha.reload();
                       }
    }
               }
           });
    }

    function showCaptcha() {
       if (!isVerify()) {
           $("#dialog-ui")
           .html('<p align="center" id="captcha_temp"><img src="/images/loader.gif" alt="Loading" /></p>')
           .dialog('option', 'title', 'Действительно ли вы человек?')
           .dialog('open');
           $.ajax({
             url: "/getkey.php",
             dataType: 'html',
             success: function(data) {
                Recaptcha.create(data, "captcha_temp", {theme: "clean"});
             }
           });
       }
    }

    function isVerify() {
       var verifyID = $.ajax({
           url: "/verify.php",
           async: false
       }).responseText;
       return (
           verifyID.replace(/^\s+|\s+$/, '') == 'yes'
       );
    }


    На страницу заталкиваем куда нибудь html-код диалога:
    <div id="dialog-ui" title="DIALOG_">
               <p>DIALOG</p>
           </div>


    И затем в <head> внедряем следующее:
    <head>
       <script type="text/javascript" src="/client.js"></script>
       <script type="text/javascript" src="http://www.google.com/recaptcha/api/js/recaptcha_ajax.js?legacy"></script>
    </head>


    Готово! Теперь чтобы вызвать всплывающую капчу вызовите метод showCaptcha(); внутри своей js-логики (например при проверке формы) и поставьте return false на submit если вы делаете к примеру регистрацию пользователя. В самом скрипте не забудьте проверить наличие nobot в сессии при регистрации. В случае если при регистрации пользователь допустил ошибку - капча не вызовется повторно так как isVerify() вернет true.

    P.S.: обратите внимания на эту вставку
    .html('<p align="center" id="captcha_temp"><img src="/images/loader.gif" alt="Loading" /></p>')

    Это показ красивого загрузчика, пока код к нам не приехал =)
    Если вы хотите использовать этот загрузчик, то сначала скачайте его (к примеру с сайта http://www.preloaders.net ), а потом не забудьте предварительно загрузить, вставив куда-нибудь на страницу в невидимом виде:
    <img src="/images/loader.gif" alt="Loading…" width="1px" height="1px" />
  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 19 сентября 2011 г. 15:09, спустя 23 часа 47 минут 30 секунд

    вау пиздота то какая!
    Сапожник без сапог
  • Абырвалг

    Сообщения: 6476 Репутация: N Группа: Джедаи

    Spritz 19 сентября 2011 г. 16:44, спустя 1 час 34 минуты 48 секунд

    как бы так сделать, что б от рекапчи получить только картинку? шатал-вертел на хую я ее кнопочки и инпут-поле, у меня свои элементы управления.
    Спустя 153 сек.
    Recaptcha.create

    а если я хочу две капчи на одной странице впендюрить? Что за апи? Нельзя было сделать что-то типа captcha1 = new Recaptcha(); captcha1.render() ?
  • phpdude

    Сообщения: 26624 Репутация: N Группа: в ухо

    Spritz 19 сентября 2011 г. 16:50, спустя 6 минут 6 секунд

    а если я хочу две капчи на одной странице впендюрить? Что за апи? Нельзя было сделать что-то типа captcha1 = new Recaptcha(); captcha1.render() ?

    если захочешь - впендюришь. в исходнике все просто.

    f = d.server + "image?c=" + d.challenge;


    где шаленж - данные из сервреа в примере вани.
    Спустя 26 сек.
    чо стонать то? программист же блядь :-)

    взял, посмотрел да сделал
    Сапожник без сапог
  • Ivan

    Сообщения: 1316 Репутация: N Группа: Адекваты

    Spritz 19 сентября 2011 г. 17:02, спустя 11 минут 51 секунду

    а если я хочу две капчи на одной странице впендюрить?

    Не совсем ясно зачем? Заставить пользователя вбить две таких капчи разом? Капчу из этого примера можно вызывать сколько угодно - нужно на стороне сервера тупо обнулять $_SESSION['nobot'] когда необходимо.

    шатал-вертел на хую я ее кнопочки и инпут-поле

    У нее есть несколько встроенных стилей (штук 5 помоему + можно свой забабахать)
    Точно знаю что частенько имиджборды балуются этим (грабят картинку рекапчи)

    Что за апи?

    А вот это сложный вопрос - оно плоховасто документировано.

    З.Ы: в рекапче два слова - первое генерируется ботом, второе берется из древней книги и частично распознается по возможности (пользователь выполняет роль машинного наборщика-переводчика сам того не замечая)

    Плюс рекапчи - минимум нагрузки на сервер и отсутствие требований графических библиотек
  • Абырвалг

    Сообщения: 6476 Репутация: N Группа: Джедаи

    Spritz 20 сентября 2011 г. 1:02, спустя 8 часов 26 секунд

    да понятно, мы ее используем на нескольких проектах. Это были так, недовольства в слух

Пожалуйста, авторизуйтесь, чтобы написать комментарий!