Javascript 带有jQuery验证插件的新reCaptcha

Javascript 带有jQuery验证插件的新reCaptcha,javascript,php,jquery,validation,recaptcha,Javascript,Php,Jquery,Validation,Recaptcha,在表单提交之前,我搜索了表单,但不知道如何使用的验证功能 我的意图: $.validator.addMethod('reCaptchaMethod', function (value, element, param) { if (grecaptcha.getResponse() == ''){ return false; } else { // I would like als

在表单提交之前,我搜索了表单,但不知道如何使用的验证功能

我的意图:

    $.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验证,以及其他验证规则

我可以在提交后检查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);
                            }
                        });
                    }

             }
submitHandler:函数(){
if(grecaptcha.getResponse()=''){
//如果出现错误,我将在div中发布消息
$(“#reCaptchaError').html(“请验证您是人类”

”); }否则{ $.ajax({ 类型:“POST”, url:“sendmail.php”, 数据:$('#form')。序列化(), 成功:功能(数据){ $('#message').html(数据); } }); } }
但我不喜欢这种方法,原因有二:

  • 它只是检查recaptcha是否已填充,而不是它是否有效,以及
  • 用户感觉这是一个两步验证
  • 他们说,可以在回调上呈现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">
    
    请注意,您必须在代码中包含
    忽略:“.ignore”
    ,因为jquery.validate默认情况下忽略隐藏字段,而不是验证它们

    如果要删除reCapcha validate上的错误消息,请向reCapcha元素添加一个数据回调

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

    我发现你的解决方案很有趣(@FabioG)

    但是,我已经对它进行了一些修改,以便自己使用,我愿意将代码共享给其他人使用

    我正在制作一个交互式表单,在您完成步骤时进行验证

    它是用来点食物的。因此,表格要求验证和激活注册按钮,并且使用最新的reCaptcha(2016年5月12日)

    此外,这段代码处理过期的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>
    
    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在此期间过期,它将使用“data expired callback”(数据过期回调)中分配的函数,从输入字段中删除令牌,并再次请求重新验证,该验证将失败,因为该字段为空。这是通过函数recaptchaExpired()实现的

    在代码的后面部分,您可以看到我们添加了一个jQuery keyup函数,用于检查重新验证,并查看用户是否已将所需信息传递到输入字段。如果信息和字段验证成功,keyup函数将启用Register按钮

    另外,我在keyup上使用了一个去盎司脚本(tnx,David Walsh)。因此它不会导致浏览器延迟。因为,会有很多输入

    但是,请记住,如果用户决定绕过reCaptcha,他总是可以在输入字段中输入“255”字符长的字符串。但是,我更进一步,制作了一个AJAX验证服务器端来确认reCaptcha。不过,我还没有将其包括在回答中

    我认为这段代码是对前面答案的一个微小改进。如果您有任何问题或需要AJAX/PHP代码,请随意评论。我会在可能的时候提供它

    这是代码笔:

    您可以在其API中找到有关reCatpcha数据属性和函数的所有信息:

    希望它能帮助别人


    关于,

    您还可以在提交程序中阻止表单提交

    $("#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')
        }
    }
    });
    

    问题是我想将captcha验证与jQuery.Validate()集成函数,因此我可以向用户显示填充字段中的单个错误列表。抱歉,但我不明白如何使用您的解决方案来实现这一点?您可以通过调用函数来实现它。就像在脚本标记中那样,u可以调用此函数,并可以执行填充函数validateForm(){//do the code here}这对我很有帮助,感谢@pguardiario提供了这个非常好的解决方案。非常简单,工作非常完美,谢谢你。只是补充一下,请确保不要放置您的recaptchaCallback()内部文档准备就绪。无法访问数据回调事件。当无效时,所需规则的函数是否应返回true?是否确定?@Phoenix_uy抱歉回答延迟。是的,这是正确的,如果验证码回答无效,则必须声明隐藏字段是必需的,在
    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);
    
    $("#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')
        }
    }
    });