简体   繁体   中英

Using ReCaptcha with jQuery Validate, giving correct response but gives error

I'm using jQuery validate with a registration form for my website with a reCaptcha at the bottom. Here is the script to check the form for errors (edited to only the relevant parts):

$(document).ready(function() { 
  jQuery.validator.addMethod("checkCaptcha", function() {
    var phpquery = $.ajax({url:"verify.php",
      type: "POST",
      async: false,
      data:{recaptcha_challenge_field:Recaptcha.get_challenge(),recaptcha_response_field:Recaptcha.get_response()},
      success:function(resp) {
        if (resp == 'false') {
          console.dir(resp);
          return false;
        } else {
          console.dir(resp);
          return true;
        }
      }
    });
  },"");

  $('#regForm').validate({
    rules:{
      recaptcha_response_field:{required:true,checkCaptcha:true}
    },
    messages:{
      recaptcha_response_field:{checkCaptcha:"Your Captcha response was incorrect. Please try again."}
    }
  });
});

What happens is when I enter the correct reCaptcha response and either click submit or tab out of the response text field, it will initially say true in the console, then immediately throw false and prevent me from submitting the form.

What also happens is when the incorrect reCaptcha response is entered, it will throw false like it's supposed to but for every letter I type in, it will submit that to verify.php and return false . When I finally get done typing in the correct reCaptcha, it doesn't recognize it as such and still returns false .

Reloading the reCaptcha also throws a false , even when the correct response is entered.

I know the verify.php works correctly, because when the <form> would have action="verify.php," everything would work perfectly (ie, tell you if you entered the correct reCaptcha, regardless of how many times you tried).

Am I missing something? Is there an easier, reliable way to do this?

Use the onkeyup: false option inside .validate() .

Otherwise, every single time you type one letter, it will run your checkCaptcha method and send an incomplete Captcha code to the server. I believe once an incorrect Captcha code is sent, it's now expired and you can't send the same code again.

Either way, I think it's best not to send a code to the server until after the field is complete.

$('#regForm').validate({
    onkeyup: false,
    rules:{
        recaptcha_response_field: {
            required: true,
            checkCaptcha: true
        }
    },
    messages:{
        recaptcha_response_field: {
            checkCaptcha: "Your Captcha response was incorrect. Please try again."
        }
    }
});

Also, if the Captcha fails, you'll need to trigger a refresh to get a new code.

Recaptcha.reload();

Inside your success callback, perhaps...

success:function(resp) {
    if (resp == 'false') {
        console.dir(resp);
        Recaptcha.reload();  // get a new captcha code on failure
        return false;
    } else {
        console.dir(resp);
        return true;
    }
}

The problem with your first addMethod validator is about how you return true or false, and the second is more complex than what it should be. I don't know how you treat the thing from server-side but maybe this code is what you need:

http://blog.netgloo.com/2014/06/03/adding-recaptcha-validator-to-jquery-validate/

That works great for me!

Alright, finally got it (although it just might be a work around). Here's the new addMethod :

jQuery.validator.addMethod("checkCaptcha", function() {
 var bfr = false;
 var phpquery = $.ajax({url:"verify.php",
  type: "POST",
  async: false,
  data:{recaptcha_challenge_field:Recaptcha.get_challenge(),recaptcha_response_field:Recaptcha.get_response()},
  complete:function(resp) {
    if(resp.responseText.indexOf("false")>=0){
     Recaptcha.reload();
    }else{
     bfr = true;
    }
  }
 });
if(bfr){
   return true;
 }
},"");

I also added onkeyup:false , onclick:false , and onfocusout:false to validate() . This seems to get the job done.

Here is my idea specially regarding ' validating captcha using AJAX request '.

the main reason for adding a captcha in a form is for a verification whether it is a bot or human who did the form submission. so even if other fields have errors, after a successful captcha submission obviously we know it is human. So, It is totally fine to remove the captcha field after its first success (please do refresh the captcha until it is a success). Then can handle other fields as usualy.

Any objections ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM