问题
I'm using custom captcha with jQuery Validation Plugin
My configuration looks like this:
$('#contactform').validate({
onkeyup: function(element, event) {
$(element).valid();
},
errorElement: 'span',
rules: {
contactform_captcha: {
minlength: 6,
maxlength: 6,
required: true,
remote: /path/to/captcha-check.php
},
},
messages: {
contactform_captcha: {
required: "No code, no email",
minlength: function () {
return [
'Enter at least ' + (6 - parseInt($('#contactform_captcha').val().length)) +
' more character(s) to go.'];
},
remote: function () {
$("#captchaimage").attr("src", /path/to/new/captcha.php+"?r=" + Math.random());
return ['Wrong code, therefore try again'];
}
},
},
success: function(label) {
label.addClass("valid").text("Well done!")
},
submitHandler: function(form) {
//submit form
}
});
$('span[class^="error"]:not(.valid)').remove();
What this code do is verify if there are 6 characters, then sends these 6 characters to captcha-check.php
. If everything is ok captcha-check.php
will return true
, else it will return false
and this function is called then:
remote: function () {
$("#captchaimage").attr("src", /path/to/new/captcha.php+"?r=" + Math.random());
return ['Wrong code, therefore try again'];
}
On false
, message function will update new src
of image #captchaimage
. Everything works, but only for the first time. I guess that remote response message is cached.
Also if i output Math.random()
in remote remote response message, it will not update and there perhaps maybe is problem.
回答1:
Your code:
messages: {
contactform_captcha: {
....
remote: function () {
$("#captchaimage").attr("src", /path/to/new/captcha.php+"?r=" + Math.random());
return ['Wrong code, therefore try again'];
}
}
}
I suggest that you convert your Math.random()
function to PHP and into your server side script, rather than having +"?r=" + Math.random()
in your JavaScript, which is not secure. After all, nothing is preventing somebody from over-riding Math.random()
and sending any number they wish.
And since the messages
option is only meant for generating custom messages, you should trigger the new captcha image upon the success
response from the remote
method instead.
Something a lot more like this...
rules: {
contactform_captcha: {
// minlength: 6, // <-- handle this in your PHP for remote
// maxlength: 6, // <-- handle this in your PHP for remote
// rangelength: [6,6], // <-- same as two rules above
required: true,
remote: {
url: '/path/to/captcha-check.php',
success: function (response) {
if (response != true) {
// trigger a new captcha code from here
$("#captchaimage").attr("src", "/path/to/new/captcha.php")
}
}
}
}
},
As per the documentation for the remote method:
The [server] response is evaluated as JSON and must be
true
for valid elements, and can be anyfalse
,undefined
ornull
for invalid elements, using the default message; or a string, eg. "That name is already taken, try peter123 instead" to display as the error message.
You could also leverage this to generate custom messages on your server side. In fact, since you need to call remote
on this field anyway, all validation rules (minlength
, maxlength
, etc.) for your contactform_captcha
field could be done server-side. Whatever string is returned from the server will automatically become the error message.
An important note:
I would disable onkeyup
validation for the contactform_captcha
field, otherwise, you're going to call the remote
method on every keystroke thereby checking the captcha code before the user finishes entering the full captcha code. This will be a major issue since it's impossible for the user to match a captcha that changes on every keystroke.
onkeyup: function(element, event) {
if ($(element).attr('name') != 'contactform_captcha') {
$(element).valid();
}
},
来源:https://stackoverflow.com/questions/20441377/jquery-validation-plugin-refresh-captcha-work-only-once