谷歌无形验证码+ jQuery验证()问题

时间:2021-11-11 11:19:15

I have implemented new Google's INVISIBLE reCaptcha on several sites successfully, however, it conflicts with jQuery validate(), in such a way that the js validation is no longer executed on button/form submit, and reCaptcha instantly kicks-in. If user forgets to fill-in a requried form field, it will have to wait for server response, and get back to it next time.

我已经成功地在几个站点上实现了新的谷歌的无形验证码,但是,它与jQuery validate()发生了冲突,以使js验证不再在按钮/表单提交上执行,并立即启动了reCaptcha。如果用户忘记填写请求的表单字段,它将不得不等待服务器响应,并在下一次返回。

jQuery .validate() supports callback, but because of the fact that it is hard-coded inside an internal class of a CMS, is there a way I can modify it somehow outside (e.g. from front-end theme, on document load, when validation code is already rendered)?

jQuery .validate()支持回调,但由于它是在CMS的内部类中硬编码的,我是否可以在外部以某种方式修改它(例如,从前端主题开始,在文档加载时,当验证代码已经呈现时)?

Or, another idea would be to postpone captcha's callback somehow, so that validation step can get a chance to run.

或者,另一个想法是以某种方式推迟captcha的回调,以便验证步骤能够得到运行的机会。

Thanks!

谢谢!

jQuery Validate form: (hard-coded in the core, can't be modified, unless I edit core file or extend class/clone function - not optimal)

jQuery验证表单:(在核心中硬编码,不能修改,除非我编辑核心文件或扩展类/克隆函数——不是最优)

<script type="text/javascript">
$(document).ready(function(){
    $("form[name=comment_form]").validate({
        rules: {
            body: {
                required: true,
                minlength: 1
            },
            authorEmail: {
                required: true,
                email: true
            }
        },
        wrapper: "li",
        errorLabelContainer: "#comment_error_list",
        invalidHandler: function(form, validator) {
            $('html,body').animate({ scrollTop: $('#comment_error_list').offset().top }, { duration: 250, easing: 'swing'});
        },
        submitHandler: function(form){
            $('button[type=submit], input[type=submit]').attr('disabled', 'disabled');
            form.submit();
        }
    });
});
</script>

reCaptcha explicit render:

reCaptcha明确的呈现:

<script type='text/javascript'>
    var renderInvisibleReCaptcha = function() {
    for (var i = 0; i < document.forms.length; ++i) {
        var form = document.forms[i];
        var holder = form.querySelector('.invisible-recaptcha');
        if (null === holder) continue;
        (function(frm){
            var holderId = grecaptcha.render(holder, {
            'sitekey': 'my-key-here',
            'badge': 'inline',
            'size': 'invisible',
            'callback': function (recaptchaToken) {HTMLFormElement.prototype.submit.call(frm);},
            'expired-callback': function(){grecaptcha.reset(holderId);}
            });
            frm.onsubmit = function (evt){evt.preventDefault();grecaptcha.execute(holderId);};
        })(form);
    }
};
</script>

4 个解决方案

#1


6  

I was having the similar problem and validated the form before executing invisible reCaptcha with the help of this link provided by Terry.

我遇到了类似的问题,在Terry提供的这个链接的帮助下,在执行看不见的验证码之前对表单进行了验证。

Here are the steps:

下面是步骤:

Add this div before the submit button in your form

在表单的submit按钮之前添加这个div

 <div id='recaptcha' class="g-recaptcha"
      data-sitekey="your_site_key"
      data-callback="onSubmit"
      data-size="invisible"></div>

Update your key as well. After the form closure add this method

同时更新你的钥匙。表单结束后添加该方法。

<script>onload();</script>

Before your form add this code

在您的表单添加此代码之前

<script>
function validate(event) {
 event.preventDefault();
 if (!document.getElementById('field').value) {
   alert("You must add text to the required field");
 } else {
   grecaptcha.execute();
 }
}

function onload() {
 var element = document.getElementById('submit');
 element.onclick = validate;
}
</script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>

Do all the validations in validate method and if all the validations are successful then execute captcha.

在validate方法中执行所有的验证,如果所有的验证都成功,那么执行captcha。

#2


1  

I had the same problem, I finally found the right way to integrate jquery validate with invisible reCaptcha. It's a mix of some of the proposed solutions here.

我遇到了同样的问题,我终于找到了正确的方法来集成jquery验证和不可见的reCaptcha。这是一些提议的解决方案的混合。

First of all, the the HTML part:

首先,HTML部分:

  <div class="g-recaptcha" data-sitekey="<your key here>"  
    data-size="invisible" 
    data-callback="formSubmit">

Then, you must implement the reCaptcha callback in that way:

然后,您必须以这种方式实现重新捕获回调:

function formSubmit(response) {
    // submit the form which now includes a g-recaptcha-response input
     $("#orderform").submit();
    return true;
}

And finally, the tricky part is in the jquery validate's submitHandler:

最后,棘手的部分在jquery validate的submitHandler中:

   submitHandler: function (form) {
        if (grecaptcha.getResponse()) {
                // 2) finally sending form data
                form.submit();
        }else{
                // 1) Before sending we must validate captcha
            grecaptcha.reset();
            grecaptcha.execute();
        }           
    }

The sequence is as follows:

序列如下:

  1. When user hits submit button, jquery's submitHandler is called, as invisible recaptcha isn't executed yet, we call grecaptcha.execute(). It takes some seconds for google's recaptcha to validate, and when it's fully validated it'll call formSubmit callback (while this callback isn't called, we cannot send form data to the server!).
  2. 当用户点击submit按钮时,会调用jquery的submitHandler,因为看不见的recaptcha还没有执行,我们将调用grecaptcha.execute()。谷歌的recaptcha验证需要几秒钟的时间,当它被完全验证时,它将调用formSubmit回调(虽然这个回调没有被调用,但是我们不能向服务器发送表单数据!)
  3. In formSubmit callback we call $('#orderform').submit to force to enter submitHandler again.
  4. 在formSubmit回调中,我们调用$('#orderform')。再次提交强制进入submitHandler。
  5. Inside submitHandler again, this time as grecaptcha.getResponse is not null, we can post the form data to the server, it will include the recaptcha hidden field, which must then be validated on the server side.
  6. 再一次,在亚米斯特勒的内部,这次是grecaptcha。getResponse不是null,我们可以将表单数据发送到服务器,它将包含recaptcha隐藏字段,然后必须在服务器端验证该字段。

Hope this helps.

希望这个有帮助。

#3


0  

I had the same issue working on classic Asp.Net Core MVC template. It was internally decorated by the Unobstrusive Validation. After inserting Invisible recaptcha, the validation was broken. Reading this article, I managed to make it working, using the integrated validation, without the need of specifying validation for every field (inferred by Model Class into MVC project)

我在经典Asp上也有同样的问题。净MVC核心模板。它的内部装饰是不受干扰的验证。插入不可见的验证码后,验证被破坏。在阅读本文时,我使用集成验证使它能够工作,而不需要为每个字段指定验证(由Model类推断为MVC项目)

HTML Page:

HTML页面:

 <input type="hidden" name="gRecaptchaResponse" id="gRecaptchaResponse" value="" /> 

            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <div id='recaptcha' class="g-recaptcha"
                         data-sitekey="@_configuration["InvisibleRecaptcha:SiteKey"]"
                         data-callback="SubmitRegistration"
                         data-size="invisible"></div>
                    <button type="submit" id="SubmitButton" class="btn btn-primary"> Invia</button>
                </div>
            </div>

Javascript Code:

Javascript代码:

 <script>

        function onload() {
            var element = document.getElementById('SubmitButton');
            element.onclick = validate;
        }
        onload();

        function validate(event) {
            event.preventDefault();

            $("#Form").validate();
            var isFormValid = $("#Form").valid();
            if (isFormValid) {
                grecaptcha.execute();
            }
        }

        function SubmitRegistration(data) {
            if ($("#gRecaptchaResponse").val() == '') {
                $("#gRecaptchaResponse").val(data);
            }
            document.getElementById("Form").submit();
        }  

    </script>

Hope this piece of code can help someone

希望这段代码可以帮助某些人

#4


0  

Technically all we "really" want to do is Programmatically bind the challenge to a button. For example:

从技术上讲,我们“真正”想做的是通过编程将挑战绑定到一个按钮上。例如:

Add this method, which we want only to execute the invisible grecaptcha instead of "real" validation

添加这个方法,我们只想执行不可见的grecaptcha,而不是“真正的”验证

 jQuery.validator.addMethod("iv_recapcha_valid", function(value, element) {
        return grecaptcha.execute();
    }, 'No message needed, grecaptcha excecuted'); 

Then add this rule to your existing rules

然后将此规则添加到现有规则中

rules: { gRecaptchaResponse: { iv_recapcha_valid: true } }

add a hidden field

添加一个隐藏字段

<input type="hidden" name="gRecaptchaResponse" value="" >

Now, "technically" the submit button is bound to the user's click action

现在,“技术上”提交按钮绑定到用户的单击操作

https://developers.google.com/recaptcha/docs/invisible

https://developers.google.com/recaptcha/docs/invisible

#1


6  

I was having the similar problem and validated the form before executing invisible reCaptcha with the help of this link provided by Terry.

我遇到了类似的问题,在Terry提供的这个链接的帮助下,在执行看不见的验证码之前对表单进行了验证。

Here are the steps:

下面是步骤:

Add this div before the submit button in your form

在表单的submit按钮之前添加这个div

 <div id='recaptcha' class="g-recaptcha"
      data-sitekey="your_site_key"
      data-callback="onSubmit"
      data-size="invisible"></div>

Update your key as well. After the form closure add this method

同时更新你的钥匙。表单结束后添加该方法。

<script>onload();</script>

Before your form add this code

在您的表单添加此代码之前

<script>
function validate(event) {
 event.preventDefault();
 if (!document.getElementById('field').value) {
   alert("You must add text to the required field");
 } else {
   grecaptcha.execute();
 }
}

function onload() {
 var element = document.getElementById('submit');
 element.onclick = validate;
}
</script>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>

Do all the validations in validate method and if all the validations are successful then execute captcha.

在validate方法中执行所有的验证,如果所有的验证都成功,那么执行captcha。

#2


1  

I had the same problem, I finally found the right way to integrate jquery validate with invisible reCaptcha. It's a mix of some of the proposed solutions here.

我遇到了同样的问题,我终于找到了正确的方法来集成jquery验证和不可见的reCaptcha。这是一些提议的解决方案的混合。

First of all, the the HTML part:

首先,HTML部分:

  <div class="g-recaptcha" data-sitekey="<your key here>"  
    data-size="invisible" 
    data-callback="formSubmit">

Then, you must implement the reCaptcha callback in that way:

然后,您必须以这种方式实现重新捕获回调:

function formSubmit(response) {
    // submit the form which now includes a g-recaptcha-response input
     $("#orderform").submit();
    return true;
}

And finally, the tricky part is in the jquery validate's submitHandler:

最后,棘手的部分在jquery validate的submitHandler中:

   submitHandler: function (form) {
        if (grecaptcha.getResponse()) {
                // 2) finally sending form data
                form.submit();
        }else{
                // 1) Before sending we must validate captcha
            grecaptcha.reset();
            grecaptcha.execute();
        }           
    }

The sequence is as follows:

序列如下:

  1. When user hits submit button, jquery's submitHandler is called, as invisible recaptcha isn't executed yet, we call grecaptcha.execute(). It takes some seconds for google's recaptcha to validate, and when it's fully validated it'll call formSubmit callback (while this callback isn't called, we cannot send form data to the server!).
  2. 当用户点击submit按钮时,会调用jquery的submitHandler,因为看不见的recaptcha还没有执行,我们将调用grecaptcha.execute()。谷歌的recaptcha验证需要几秒钟的时间,当它被完全验证时,它将调用formSubmit回调(虽然这个回调没有被调用,但是我们不能向服务器发送表单数据!)
  3. In formSubmit callback we call $('#orderform').submit to force to enter submitHandler again.
  4. 在formSubmit回调中,我们调用$('#orderform')。再次提交强制进入submitHandler。
  5. Inside submitHandler again, this time as grecaptcha.getResponse is not null, we can post the form data to the server, it will include the recaptcha hidden field, which must then be validated on the server side.
  6. 再一次,在亚米斯特勒的内部,这次是grecaptcha。getResponse不是null,我们可以将表单数据发送到服务器,它将包含recaptcha隐藏字段,然后必须在服务器端验证该字段。

Hope this helps.

希望这个有帮助。

#3


0  

I had the same issue working on classic Asp.Net Core MVC template. It was internally decorated by the Unobstrusive Validation. After inserting Invisible recaptcha, the validation was broken. Reading this article, I managed to make it working, using the integrated validation, without the need of specifying validation for every field (inferred by Model Class into MVC project)

我在经典Asp上也有同样的问题。净MVC核心模板。它的内部装饰是不受干扰的验证。插入不可见的验证码后,验证被破坏。在阅读本文时,我使用集成验证使它能够工作,而不需要为每个字段指定验证(由Model类推断为MVC项目)

HTML Page:

HTML页面:

 <input type="hidden" name="gRecaptchaResponse" id="gRecaptchaResponse" value="" /> 

            <div class="form-group">
                <div class="col-md-offset-2 col-md-10">
                    <div id='recaptcha' class="g-recaptcha"
                         data-sitekey="@_configuration["InvisibleRecaptcha:SiteKey"]"
                         data-callback="SubmitRegistration"
                         data-size="invisible"></div>
                    <button type="submit" id="SubmitButton" class="btn btn-primary"> Invia</button>
                </div>
            </div>

Javascript Code:

Javascript代码:

 <script>

        function onload() {
            var element = document.getElementById('SubmitButton');
            element.onclick = validate;
        }
        onload();

        function validate(event) {
            event.preventDefault();

            $("#Form").validate();
            var isFormValid = $("#Form").valid();
            if (isFormValid) {
                grecaptcha.execute();
            }
        }

        function SubmitRegistration(data) {
            if ($("#gRecaptchaResponse").val() == '') {
                $("#gRecaptchaResponse").val(data);
            }
            document.getElementById("Form").submit();
        }  

    </script>

Hope this piece of code can help someone

希望这段代码可以帮助某些人

#4


0  

Technically all we "really" want to do is Programmatically bind the challenge to a button. For example:

从技术上讲,我们“真正”想做的是通过编程将挑战绑定到一个按钮上。例如:

Add this method, which we want only to execute the invisible grecaptcha instead of "real" validation

添加这个方法,我们只想执行不可见的grecaptcha,而不是“真正的”验证

 jQuery.validator.addMethod("iv_recapcha_valid", function(value, element) {
        return grecaptcha.execute();
    }, 'No message needed, grecaptcha excecuted'); 

Then add this rule to your existing rules

然后将此规则添加到现有规则中

rules: { gRecaptchaResponse: { iv_recapcha_valid: true } }

add a hidden field

添加一个隐藏字段

<input type="hidden" name="gRecaptchaResponse" value="" >

Now, "technically" the submit button is bound to the user's click action

现在,“技术上”提交按钮绑定到用户的单击操作

https://developers.google.com/recaptcha/docs/invisible

https://developers.google.com/recaptcha/docs/invisible