Новый reCaptcha с плагином проверки jQuery

Я много искал, но не могу понять, как проверить новый reCaptcha перед представлением формы вместе с функцией проверки правильности плагин проверки jQuery.

Я имею в виду что-то вроде этого:

    $.validator.addMethod('reCaptchaMethod', function (value, element, param) {
            if (grecaptcha.getResponse() == ''){
                return false;
            } else {
                // I would like also to check server side if the recaptcha response is good
                return true
            }
        }, 'You must complete the antispam verification');


    $("#form").validate({
            rules: {
                name: {
                    required: true,
                    minlength: 2
                },
                email: {
                    required: true,
                    email: true
                },
                reCaptcha: {
                    reCaptchaMethod: true   
                }
            },
            messages: {
                name: "Please fill your name",
                email: "Please use a valid email address"
            },
            submitHandler : function () {
                        $.ajax({
                            type : "POST",
                            url : "sendmail.php",
                            data : $('#form').serialize(),
                            success : function (data) {
                                $('#message').html(data);
                            }
                        });
                    }


        });

В нескольких словах я хотел бы проверить serveride с помощью удаленного метода, если пользователь прошел проверку recaptcha перед отправкой формы, а также другие правила проверки.

Я могу проверить ответ recaptcha AFTER (на sendmail.php), но было бы лучше иметь ответ проверки recaptcha вместе с другими проверками полей.

Основная причина заключается в улучшении пользовательского интерфейса, причем все поля проверяются сразу.

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

            submitHandler : function () {
                  if (grecaptcha.getResponse() == ''){
                      // if error I post a message in a div
                      $( '#reCaptchaError' ).html( '<p>Please verify youare human</p>' );

                  } else {

                        $.ajax({
                            type : "POST",
                            url : "sendmail.php",
                            data : $('#form').serialize(),
                            success : function (data) {
                                $('#message').html(data);
                            }
                        });
                    }

             }

Но мне не нравятся по двум причинам: 1) Я просто проверяю, заполнен ли recaptcha, а не если он действителен. 2) Пользователь чувствует себя как двухэтапная проверка.

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

Я попытался реализовать это, но я не смог использовать это решение в правиле функции validate().

Любые подсказки приветствуются!

Ответы

Ответ 1

Я знаю, что этот вопрос немного устарел, но у меня была та же проблема, и я только что нашел решение. Вы можете сделать это, добавив скрытое поле рядом с div reCaptcha, например:

<div class="g-recaptcha" data-sitekey="{YOUR-SITE-KEY-HERE}"></div>
<input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha" id="hiddenRecaptcha">

тогда в вашем javascript:

$("#form").validate({
        ignore: ".ignore",
        rules: {
            name: {
                required: true,
                minlength: 2
            },
            email: {
                required: true,
                email: true
            },
            hiddenRecaptcha: {
                required: function () {
                    if (grecaptcha.getResponse() == '') {
                        return true;
                    } else {
                        return false;
                    }
                }
            }
        },(...rest of your code)

ЗАМЕТЬТЕ, ЧТО ВЫ ДОЛЖНЫ ИМЕТЬ ignore: ".ignore" в своем коде, потому что jquery.validate по умолчанию игнорирует скрытые поля, а не проверяет их.

Если вы хотите удалить сообщение об ошибке при проверке reCapcha, добавьте обратный вызов данных в элемент reCapcha

<div class="g-recaptcha" data-sitekey="{YOUR-SITE-KEY-HERE}" data-callback="recaptchaCallback"></div>

А потом в свой файл JS добавить

function recaptchaCallback() {
  $('#hiddenRecaptcha').valid();
};

Ответ 2

Вы также можете запретить отправку формы в submitHandler

$("#loginForm").validate({
rules: {
    username: {
        required: true,
        minlength: 6
    },
    password: {
        required: true,
    },
},
submitHandler: function(form) {
    if (grecaptcha.getResponse()) {
        form.submit();
    } else {
        alert('Please confirm captcha to proceed')
    }
}
});

Ответ 3

Я нашел ваше решение интересным (@FabioG).

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

Я работал над интерактивной формой, подтвержденной по мере выполнения шагов.

Он использовался для заказа пищи. Ergo, форма требует проверки и активации кнопки регистрации, и она использует последнюю reCaptcha на дату (5/12/2016).

Кроме того, этот код обрабатывает истекую reCaptcha, проверку на стороне сервера через ajax (тесто не включается - если кому-то это нужно, не стесняйтесь комментировать мой ответ, и я отредактирую его соответствующим образом).

Давайте начнем.

Код HTML:

<form id="registerForm" method="get" action="">
<fieldset class="step-1">
<h4>Step One:</h4>
<span class="clock">Register under one minute!</span>
<label for="email-register" class="label">E-mail*</label>
<input id="email-register" name="email-register" type="email" value="" autocomplete="off"/>

<label for="password-register" class="label">Password*</label>
<input id="password-register" name="password-register" type="password" value="" autocomplete="off"/>

<div class="g-recaptcha" data-sitekey="6LeS4O8SAAAAALWqAVWnlcB6TDeIjDDAqoWuoyo9" data-callback="recaptchaCallback" data-expired-callback="recaptchaExpired" style="margin-top: 3rem;"></div>
<input id="hidden-grecaptcha" name="hidden-grecaptcha" type="text" style="opacity: 0; position: absolute; top: 0; left: 0; height: 1px; width: 1px;"/>
</div>
</fieldset>
<fieldset class="step-2">
<h4>Step two:</h4>
<span class="notice">All fields with a sign are required!*</span>
<label for="first-name" class="label">First Name*</label>
<input name="first-name" id="first-name" type="text" value="" />

<label for="last-name" class="label">Last Name*</label>
<input name="last-name" id="last-name" type="text" value="" />

<label for="address" class="label">Address*</label> 
<input name="address" id="address" type="text" value=""/>

<label for="entrance" class="label">Entrance</label>    
<input name="entrance" id="entrance" type="text" value=""/>

<label for="apartment-number" class="label">Apartment #</label>
<input name="apartment-number" id="apartment-number" type="text" value="" />

<label for="inter-phone" class="label">Interphone</label>           
<input name="inter-phone" id="inter-phone" type="text" value=""/>

<label for="telephone" class="label">Mobile Number*</label>
<input name="telephone" id="telephone" type="text" value="" />

<label for="special-instructions" class="label">Special Instructions</label>    
<textarea name="special-instructions" id="special-instructions"></textarea>
<div>
</fieldset>
<button class="button-register" disabled>Register</button>
</form>

Итак, как вы видите, кнопка для отправки ( ".button-register" ) первоначально отключена.

Вы можете включить его только путем заполнения полей обязательно (*).

Пожалуйста, имейте в виду, что я не добавил CSS. Форма находится на медвежьем минимуме и предназначена только для образовательных целей.

Немногие вещи, которые отличаются от @FabioG, отвечают:

Нет необходимости скрывать элемент или использовать ".ignore". Я скрыл его с встроенным CSS.

Существует ответ ответа для успешной reCaptcha и истекшего reCaptcha.

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

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

Перейдем к JavaScript/jQuery.

JavaScript/JQuery:

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};
function recaptchaCallback() {
    var response = grecaptcha.getResponse(),
        $button = jQuery(".button-register");
    jQuery("#hidden-grecaptcha").val(response);
    console.log(jQuery("#registerForm").valid());
    if (jQuery("#registerForm").valid()) {
        $button.attr("disabled", false);
    }
    else {
        $button.attr("disabled", "disabled");
    }
}

function recaptchaExpired() {
    var $button = jQuery(".button-register");
    jQuery("#hidden-grecaptcha").val("");
    var $button = jQuery(".button-register");
    if (jQuery("#registerForm").valid()) {
        $button.attr("disabled", false);
    }
    else {
        $button.attr("disabled", "disabled");
    }
}
function submitRegister() {
  //ajax stuff
}
(function ($, root, undefined) {
    $(function () {
        'use strict';
        jQuery("#registerForm").find("input").on("keyup", debounce(function() {
          var $button = jQuery(".button-register");
          if (jQuery("#registerForm").valid()) {
            $button.attr("disabled", false);
          }
          else {
            $button.attr("disabled", "disabled");
          }
        }, 1000));
        jQuery("#registerForm").validate({
          rules: {
            "email-register": {
              required: true,
              email: true
            },
            "password-register": {
              required: true,
              minlength: "6"
            },
            "first-name": "required",
            "last-name": "required",
            address: "required",
            telephone: "required",
            "hidden-grecaptcha": {
              required: true,
              minlength: "255"
            }
          },
          messages: {
            "email-register": "Enter valid e-mail address",
            "password-register": {
              required: "Enter valid password",
              minlength: "Password must be bigger then 6 chars!"
            },
            "first-name": "Required!",
            "last-name": "Required!",
            address: "Required!",
            telephone: "Required!"
          },
          submitHandler: submitRegister
        });
    }); 
})(jQuery, this);

Как вы можете видеть здесь, есть несколько функций: recaptchaCallback() и recaptchaExpired().

recaptchaCallback(), который встроен через data-callback данных данных, использует grecaptcha.getResponse(), чтобы проверить, проверена ли reCaptcha, если она входит токен в скрытое поле ввода и запрашивает повторную валидацию через jQuery ("# ​​registerForm).validate();.

Однако, если reCaptcha истекает, тем временем он будет использовать назначенную функцию в "обратном вызове с прошлым", чтобы удалить токен из поля ввода и снова запросить повторную проверку, которая не будет выполнена, потому что это поле пустой. Это достигается с помощью функции recaptchaExpired().

Позже в коде вы увидите, что мы добавили функцию jQuery keyup, чтобы проверить повторную валидацию и посмотреть, прошел ли пользователь по необходимой информации в поля ввода. Если информация и поле успешно подтвердятся, функция keyup активирует кнопку Регистрация.

Кроме того, я использовал debounce script (tnx, David Walsh) в keyup. Таким образом, это не вызывает отставание браузера. Так как было бы много печатать.

Но имейте в виду, если пользователь решает обойти reCaptcha, он всегда может просто ввести длинную строку символов "255" в поле ввода. Но я сделал еще один шаг и сделал сервер проверки сервера AJAX для подтверждения reCaptcha. Тесто, я не включил его в ответ.

Он считает, что этот код является незначительным улучшением предыдущего ответа. Если у вас есть какие-либо вопросы или вам нужен код AJAX/PHP, не стесняйтесь комментировать. Я поставлю его, когда смогу.

Здесь также кодируется: reCaptcha с jQuery.validation

Вы можете найти всю информацию о атрибутах и ​​функциях данных reCatpcha в их api здесь: reCaptcha API

Надеюсь, это помогло кому-то!

Привет,

Ответ 4

Я боролся с этим сегодня и в итоге пошел с:

<form onsubmit="return $(this).valid() && grecaptcha.getResponse() != ''">

Это просто похоже на самый простой способ сделать это. Кто-то обязан жаловаться на включение js inline, но я в порядке с ним.