Я много искал, но я не могу понять, как проверить новый 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 ПОСЛЕ отправки (на 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 ().
Любой намек приветствуется!
Я знаю, что этот вопрос немного устарел, но у меня была такая же проблема, и я нашел решение. Вы можете сделать это, добавив скрытое поле рядом с 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(); };
Я нашел ваше решение интересным (@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);
-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);
в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 (), который внедряется через данные -обратный вызов атрибута данных , использует grecaptcha.getResponse (), чтобы проверить, проверена ли reCaptcha, если она вводит токен в скрытое поле ввода и запрашивает повторную проверку через jQuery ( "#registerForm) .validate ();.
Однако, если истечение срока действия reCaptcha истекает, то он будет использовать назначенную функцию в «обратном вызове с прошлым», чтобы удалить токен из поля ввода и снова запросить повторную проверку, которая не будет выполнена, потому что поле пуст. Это достигается с помощью функции recaptchaExpired () .
Позже в коде вы увидите, что мы добавили функцию jQuery keyup , чтобы проверить повторную проверку и посмотреть, прошел ли пользователь по необходимой информации в поля ввода. Если информация и поле успешно подтвердятся, функция keyup активирует кнопку Register .
Кроме того, я использовал сценарий debounce (tnx, David Walsh) для активации ключей. Таким образом, это не вызывает отставание браузера. С тех пор было бы много печатать.
Но имейте в виду, если пользователь решает обойти reCaptcha, он всегда может просто ввести длинную строку символов «255» в поле ввода. Но я сделал еще один шаг и сделал сервер проверки сервера AJAX для подтверждения reCaptcha. Тесто, я не включил его в ответ.
Он считает, что этот код является незначительным улучшением предыдущего ответа. Если у вас есть какие-либо вопросы или вам нужен код AJAX / PHP, не стесняйтесь комментировать. Я поставлю его, когда смогу.
Heres codepen также: reCaptcha с jQuery.validation
Вы можете найти всю информацию о атрибутах и функциях данных reCatpcha в их api здесь: reCaptcha API
Надеюсь, это помогло кому-то!
С Уважением,
Сегодня я боролся с этим и закончил:
<form onsubmit="return $(this).valid() && grecaptcha.getResponse() != ''">
Это просто похоже на самый простой способ сделать это. Кто-то обязан жаловаться на то, чтобы вставить js inline, но я в порядке.
Вы также можете запретить отправку формы в 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') } } });