0

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 (i.e., 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?

4 Answers 4

4

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;
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

So this resolves the issue of sending the response for every keystroke, but I'm still having the issue where verify.php will initially give me true then go straight to false, preventing the page from submitting.
@synthrom, yeah, even though we disabled the onkeyup event, the rule is still being evaluated on every blur and then again when submit is clicked. You can not keep sending the same code to the server. Somehow you need to check once and disable the method as soon as the code is correct.
I've added onlick:false and onfocusout:false to validate(), so that seems to take care of those issues. The addMethod is returning true but it is still throwing the error message "Your Captcha response was incorrect. Please try again." and I can't figure out why...
I'm not in a place where I can help much yet. Meanwhile, investigate using the remote method instead of your custom.
1

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!

Comments

0

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.

Comments

-1

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 ?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.