带有 jQuery 验证插件的新 reCaptcha
New reCaptcha with jQuery Validation Plugin
我搜索过但不知道如何validate the new reCaptcha, before form submit, along with the validate function of jQuery validation Plugin。
我的意图:
$.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);
}
});
}
});
简而言之:如果用户在提交表单之前通过了 recaptcha 验证以及其他验证规则,我想使用 remote method 检查服务器端。
我可以检查 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);
}
});
}
}
但我不喜欢这种方法,原因有两个:
- 它只是检查recaptcha是否已被填充,而不是它是否有效,并且
- 用户觉得这是两步验证。
In this answer 他们说可以在回调中渲染 Recaptcha,以指定对成功的 CAPTCHA 响应的函数调用。
我尝试实现它,但我无法在 validate() 函数的规则中使用此解决方案。
我今天在这个问题上苦苦挣扎,结果是:
<form onsubmit="return $(this).valid() && grecaptcha.getResponse() != ''">
感觉这是最简单的方法。一定有人会抱怨像那样将 js 内联,但我同意。
我知道这个问题有点过时了,但我遇到了同样的问题并且刚刚找到了解决方案。
您可以通过在 reCaptcha div 旁边添加一个隐藏字段来做到这一点,例如:
<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 验证时的错误消息,请将 data-callback 添加到 reCapcha 元素
<div class="g-recaptcha" data-sitekey="{YOUR-SITE-KEY-HERE}" data-callback="recaptchaCallback"></div>
然后在你的js文件中添加
function recaptchaCallback() {
$('#hiddenRecaptcha').valid();
};
我发现您的解决方案很有趣 (@FabioG)。
但是,我已经对其进行了一些修改以供自己使用,我愿意将代码共享给其他人使用。
我正在制作一个交互式表单,它会在您完成步骤时进行验证。
用于点餐。因此,该表格需要验证和激活注册按钮,并且它使用的是最新的 reCaptcha(2016 年 5 月 12 日)。
此外,此代码通过 ajax 处理过期的 reCaptcha、服务器端验证(尽管不包括在内——如果有人需要它,请随时对我的回答发表评论,我会相应地对其进行编辑)。
让我们开始吧。
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 同时过期,它将使用“data-expired-callback”中指定的函数,从输入字段中删除令牌并再次要求重新验证,这将失败,因为字段为空。这是通过函数 recaptchaExpired().
实现的
在后面的代码中,你可以看到我们添加了一个jQuery keyup 函数,用于检查重新验证并查看用户是否已通过输入字段所需的信息。如果信息和字段验证成功,keyup 函数将启用 Register 按钮。
另外,我在 keyup 上使用了去抖动脚本(tnx,David Walsh)。所以它不会导致浏览器延迟。因为,会有很多打字。
但是请记住,如果用户决定绕过 reCaptcha,他总是可以在输入字段中输入“255”字符长的字符串。但是,我更进一步,在服务器端进行了 AJAX 验证以确认 reCaptcha。不过,我没有将其包含在答案中。
我认为这段代码比之前的答案略有改进。如果您有任何问题或需要 AJAX/PHP 代码,请随时发表评论。有空我会补上。
这里还有代码笔:reCaptcha with jQuery.validation
您可以在 API 此处找到有关 reCatpcha 数据属性和函数的所有信息:reCaptcha API
希望对大家有所帮助!
此致,
您还可以在 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')
}
}
});
我搜索过但不知道如何validate the new reCaptcha, before form submit, along with the validate function of jQuery validation Plugin。
我的意图:
$.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);
}
});
}
});
简而言之:如果用户在提交表单之前通过了 recaptcha 验证以及其他验证规则,我想使用 remote method 检查服务器端。
我可以检查 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);
}
});
}
}
但我不喜欢这种方法,原因有两个:
- 它只是检查recaptcha是否已被填充,而不是它是否有效,并且
- 用户觉得这是两步验证。
In this answer 他们说可以在回调中渲染 Recaptcha,以指定对成功的 CAPTCHA 响应的函数调用。
我尝试实现它,但我无法在 validate() 函数的规则中使用此解决方案。
我今天在这个问题上苦苦挣扎,结果是:
<form onsubmit="return $(this).valid() && grecaptcha.getResponse() != ''">
感觉这是最简单的方法。一定有人会抱怨像那样将 js 内联,但我同意。
我知道这个问题有点过时了,但我遇到了同样的问题并且刚刚找到了解决方案。 您可以通过在 reCaptcha div 旁边添加一个隐藏字段来做到这一点,例如:
<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 验证时的错误消息,请将 data-callback 添加到 reCapcha 元素
<div class="g-recaptcha" data-sitekey="{YOUR-SITE-KEY-HERE}" data-callback="recaptchaCallback"></div>
然后在你的js文件中添加
function recaptchaCallback() {
$('#hiddenRecaptcha').valid();
};
我发现您的解决方案很有趣 (@FabioG)。
但是,我已经对其进行了一些修改以供自己使用,我愿意将代码共享给其他人使用。
我正在制作一个交互式表单,它会在您完成步骤时进行验证。
用于点餐。因此,该表格需要验证和激活注册按钮,并且它使用的是最新的 reCaptcha(2016 年 5 月 12 日)。
此外,此代码通过 ajax 处理过期的 reCaptcha、服务器端验证(尽管不包括在内——如果有人需要它,请随时对我的回答发表评论,我会相应地对其进行编辑)。
让我们开始吧。
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 同时过期,它将使用“data-expired-callback”中指定的函数,从输入字段中删除令牌并再次要求重新验证,这将失败,因为字段为空。这是通过函数 recaptchaExpired().
实现的在后面的代码中,你可以看到我们添加了一个jQuery keyup 函数,用于检查重新验证并查看用户是否已通过输入字段所需的信息。如果信息和字段验证成功,keyup 函数将启用 Register 按钮。
另外,我在 keyup 上使用了去抖动脚本(tnx,David Walsh)。所以它不会导致浏览器延迟。因为,会有很多打字。
但是请记住,如果用户决定绕过 reCaptcha,他总是可以在输入字段中输入“255”字符长的字符串。但是,我更进一步,在服务器端进行了 AJAX 验证以确认 reCaptcha。不过,我没有将其包含在答案中。
我认为这段代码比之前的答案略有改进。如果您有任何问题或需要 AJAX/PHP 代码,请随时发表评论。有空我会补上。
这里还有代码笔:reCaptcha with jQuery.validation
您可以在 API 此处找到有关 reCatpcha 数据属性和函数的所有信息:reCaptcha API
希望对大家有所帮助!
此致,
您还可以在 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')
}
}
});