Javascript 带有 jQuery 验证插件的新 reCaptcha
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29563822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
New reCaptcha with jQuery Validation Plugin
提问by bluantinoo
I searched and can't figure out how to validate the new reCaptcha, before form submit, along with the validate function of jQuery validation Plugin.
我搜索并无法弄清楚如何在表单提交之前验证新的 reCaptcha以及jQuery 验证插件的验证功能。
My intent:
我的意图:
$.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);
}
});
}
});
In a few words: I would like to check server-side, with the remote method, if the user has passed the recaptcha validation BEFORE submitting the form, along with other rules of validation.
简而言之:我想使用远程方法检查服务器端,如果用户在提交表单之前通过了 recaptcha 验证,以及其他验证规则。
I'm able to check the recaptcha AFTERsubmission (on sendmail.php), but it would be nicer to have the recaptcha validation response along with other fields validation.
我可以在提交后检查 recaptcha (在 sendmail.php 上),但最好有 recaptcha 验证响应以及其他字段验证。
The main reason is for a better user experience, having all fields checked at once.
主要原因是为了更好的用户体验,一次检查所有字段。
I've managed to achieve this, moving the check inside the submitHandler:
我设法实现了这一点,将检查移到 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);
}
});
}
}
But I don't like this approach, for 2 reasons:
但我不喜欢这种方法,原因有二:
- It is just checking if the recaptcha has been filled, not if it's valid, and
- User feels like it is a 2 step verification.
- 它只是检查 recaptcha 是否已填写,而不是检查是否有效,并且
- 用户感觉这是一个两步验证。
In this answerthey say it can be done rendering the Recaptcha on a callback, to specify a function call on a successful CAPTCHA response.
在这个答案中,他们说可以在回调上渲染 Recaptcha,以在成功的 CAPTCHA 响应上指定函数调用。
I tried to implement that, but I've not been able to use this solution within a rule of the validate() function.
我试图实现它,但我无法在 validate() 函数的规则中使用这个解决方案。
回答by FabioG
I know this question is a bit dated but I was having the same problem and just found the solution. You can do this by adding a hidden field next to the reCaptcha div, like:
我知道这个问题有点过时了,但我遇到了同样的问题,刚刚找到了解决方案。您可以通过在 reCaptcha div 旁边添加一个隐藏字段来做到这一点,例如:
<div class="g-recaptcha" data-sitekey="{YOUR-SITE-KEY-HERE}"></div>
<input type="hidden" class="hiddenRecaptcha required" name="hiddenRecaptcha" id="hiddenRecaptcha">
then in your javascript:
然后在你的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)
NOTICE THAT YOU MUST HAVEthe ignore: ".ignore"in your code because jquery.validate ignores hidden fields by default, not validating them.
请注意ignore: ".ignore",您的代码中必须包含,因为 jquery.validate 默认情况下会忽略隐藏字段,而不是验证它们。
If you want to remove the error message on reCapcha validate add a data-callback to the reCapcha element
如果要删除 reCapcha 验证中的错误消息,请向 reCapcha 元素添加数据回调
<div class="g-recaptcha" data-sitekey="{YOUR-SITE-KEY-HERE}" data-callback="recaptchaCallback"></div>
And then in your js file add
然后在你的 js 文件中添加
function recaptchaCallback() {
$('#hiddenRecaptcha').valid();
};
回答by Ranjith Singhu
You can also prevent the form submit in the submitHandler
您还可以在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')
}
}
});
回答by steviss
I've found your solution to be interesting (@FabioG).
我发现您的解决方案很有趣(@FabioG)。
But, I've modified it for use a bit by myself and I'm willing to share the code for others to use.
但是,我已经修改了它以供自己使用,并且我愿意共享代码供其他人使用。
I was working on an interactive form, that validated as you completed steps.
我正在开发一个交互式表单,在您完成步骤时进行验证。
It was used for ordering food. Ergo, the form required verification and activation of the register button and it is using the latest reCaptcha to date (5/12/2016).
它用于订购食物。因此,该表单需要验证和激活注册按钮,并且使用的是迄今为止最新的 reCaptcha(2016 年 5 月 12 日)。
Also, this code handles expired reCaptcha, server side verification via ajax (dough not included - if someone needs it feel free to comment my answer and I'll edit it accordingly).
此外,此代码处理过期的 reCaptcha,通过 ajax 进行服务器端验证(不包括面团 - 如果有人需要,请随时评论我的答案,我会相应地对其进行编辑)。
Lets get started.
让我们开始吧。
The HTML code:
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>
So as you can see, the button for submission (".button-register") is initially disabled.
如您所见,提交按钮(“.button-register”)最初是禁用的。
You can only enable it by filling the mandatory(*) fields.
您只能通过填写必填(*) 字段来启用它。
Please, keep in mind that I didn't include any CSS. The form is on a bear minimum and is just for educational purposes.
请记住,我没有包含任何 CSS。该表格是最低限度的,仅用于教育目的。
Few things that differ from @FabioG, answer are:
与@FabioG 不同的几件事,答案是:
There is no need to hide the element or use the ".ignore". I've hidden it with inline CSS.
无需隐藏元素或使用“.ignore”。我用内联 CSS 隐藏了它。
There is a response callbackfor successful reCaptcha and expired reCaptcha.
有成功的 reCaptcha 和过期的 reCaptcha的响应回调。
So, if your reCaptcha expires while filling out the form it will make it invalidand the button will be disabledagain.
因此,如果您的 reCaptcha 在填写表单时过期,它将使其无效并且该按钮将再次被禁用。
As well, the form uses an input field (the hidden input field) to pass the information onto AJAX(PHP later on) and verify it server side (It is a potential security risk, I covered it more at the end of the text).
同样,表单使用输入字段(隐藏输入字段)将信息传递到 AJAX(稍后使用 PHP)并在服务器端对其进行验证(这是一个潜在的安全风险,我在文末详细介绍了它) .
Lets move on to the JavaScript/jQuery.
让我们继续讨论 JavaScript/jQuery。
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);
As you can see here, there are a few functions: recaptchaCallback()and recaptchaExpired().
正如你在这里看到的,有几个函数:recaptchaCallback()和recaptchaExpired()。
recaptchaCallback()that is embeded via the data attribute data-callback, uses the grecaptcha.getResponse()to see if the reCaptcha is validated, if so it enters the token to the hidden input field and asks for re-validation via the jQuery("#registerForm).validate();.
通过数据属性data-callback嵌入的recaptchaCallback()使用grecaptcha.getResponse()来查看 reCaptcha 是否已验证,如果是,则将令牌输入隐藏的输入字段并通过jQuery( "#registerForm).validate();。
However, if the reCaptcha expires in the meanwhile it will use the assigned function in the "data-expired-callback", to remove the token from the input field and ask for re-validation again which will fail because the field is empty. This is achieved with the function recaptchaExpired().
但是,如果同时 reCaptcha 过期,它将使用“数据过期回调”中分配的函数,从输入字段中删除令牌并再次请求重新验证,这将失败,因为该字段为空。这是通过函数recaptchaExpired() 实现的。
Later in the code you can see that we added a jQuery keyupfunction, to check for re-validation and see if the user has passed on the required information to the input fields. If the information and the field validate successfully the keyupfunction will enable the Registerbutton.
在代码的后面,您可以看到我们添加了一个 jQuery keyup函数,以检查重新验证并查看用户是否已将所需信息传递给输入字段。如果信息和字段验证成功,keyup功能将启用注册按钮。
Also, I've used a debounce script (tnx, David Walsh) on keyup. So it doesn't cause browser lag. Since, there would be a lot of typing.
另外,我在keyup上使用了去抖动脚本(tnx,David Walsh)。所以它不会导致浏览器延迟。因为,会有很多打字。
But, keep in mind if a user decides to circumvent the reCaptcha he can always just enter "255" character long string to the input field. But, I've went a step further and made an AJAX verification server side to confirm the reCaptcha. Dough, I haven't included it in the answer.
但是,请记住,如果用户决定绕过 reCaptcha,他总是可以在输入字段中输入“255”个字符长的字符串。但是,我更进一步,做了一个 AJAX 验证服务器端来确认 reCaptcha。面团,我没有把它包括在答案中。
It think this code is a marginal improvement on the previous answer. If you have any questions or need the AJAX/PHP code feel free to comment. I'll supply it when I can.
它认为此代码是对先前答案的微小改进。如果您有任何问题或需要 AJAX/PHP 代码,请随时发表评论。我会在我可以的时候提供它。
Heres the codepen as well: reCaptcha with jQuery.validation
这里也是代码笔:reCaptcha with jQuery.validation
You can find all the information regarding the reCatpcha data-attributes and functions in their api here: reCaptcha API
您可以在此处的 api 中找到有关 reCatpcha 数据属性和函数的所有信息:reCaptcha API
Hope it helped someone!
希望它对某人有所帮助!
Regards,
问候,
回答by pguardiario
I struggled with this one today and ended up going with:
我今天在这个问题上挣扎,最终选择了:
<form onsubmit="return $(this).valid() && grecaptcha.getResponse() != ''">
Which just feels like the simplest way to do it. Someone is bound to complain about putting js inline like that but I'm ok with it.
这只是感觉最简单的方法。有人肯定会抱怨像这样将 js 内联,但我可以接受。

