jquery.validate 1.7版本(remote方法)bug修复方法(二)

前几天向大家介绍了关于 jquery.validate 1.7版本(remote方法)bug修复方法,那段时间恰逢一个产品上线,在表单验证时,唯独remote验证不能正常工作.因此在网上找到了该解决办法.说实话,外国友人的这个解决方法,还是不太懂,但还是感谢他才能顺利交付任务.今天有时间,做了一些自己的分析,与大家分享.

     使用工具:firefox,firebug.

     以下是一个简单的执行环境(引用库:jquery-1.5.1.js,jquery.validate-1.7.js):

客户端:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<%@ Page Language= "C#" AutoEventWireup= "true"  CodeFile= "Default.aspx.cs" Inherits= "_Default" %>
  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
  
<html xmlns= "http://www.w3.org/1999/xhtml" >
<head runat= "server" >
     <title>无标题页</title>
     <script type= "text/javascript" src= "js/jquery-1.5.1.js" ></script>
     <script src= "js/jquery.validate.js" type= "text/javascript" ></script>
     <script language= "javascript" >
         $( function (){
             $( "#form1" ).validate({
                 rules:{
                     email:{
                         required: true
                         ,remote:{
                             url: "Handler.ashx"
                             ,type: "post"
                             ,data:{ "key" : function (){
                                 return $( "#email" ).val() ;
                             }
                          }
                           
                        }
                     }
                 }
                 ,messages:{
                     email:{
                         remote: "该邮箱已存在"
                     }
                
             })
         })
     </script>
</head>
<body>
     <form id= "form1" runat= "server" >
     <div>
       <input type= "text" id = "email" name = "email" />
       <input type = "submit"  value = "提交" />
     </div>
     </form>
</body>
</html>

服务端:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<%@ WebHandler Language= "C#" Class= "Handler" %>
  
using System;
using System.Web;
  
public class Handler : IHttpHandler {
      
     public void ProcessRequest (HttpContext context) {
         context.Response.ContentType = "text/plain" ;
         string key = context.Request[ "key" ];
         if (key == "[email protected]" )
         {
             context.Response.Write( "false" );
         }
         else
         {
             context.Response.Write( "true" );
         }
     }
   
     public bool IsReusable {
         get {
             return false ;
         }
     }
  
}

先做一个非空测试,不输入任何内容,点击提交,如下结果.

jquery.validate 1.7版本(remote方法)bug修复方法(二)_第1张图片

 

非空验证正常,再来测试remote验证,输入[email protected],点击提交,如下结果

jquery.validate 1.7版本(remote方法)bug修复方法(二)_第2张图片

 

没有任何反应,我们尝试检测抛出的异常,因为remote的核心是ajax到远程服务器验证.如下代码检测jquery抛出异常:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$( function (){
             $( "#form1" ).validate({
                 rules:{
                     email:{
                         required: true
                         ,remote:{
                             url: "Handler.ashx"
                             ,type: "post"
                             ,data:{ "key" : function (){
                                 return $( "#email" ).val() ;
                             }
                             ,error: function (a,b,c){
                                 alert(a + " " + b + " " + c);
                             }
                          }
                           
                        }
                     }
                 }
                 ,messages:{
                     email:{
                         remote: "该邮箱已存在"
                     }
                
             })
         })

在error代码块中捕获到了错误,但没有任何提示,如下:

jquery.validate 1.7版本(remote方法)bug修复方法(二)_第3张图片

     可能作者并没有把异常具体信息抛出来.没关系,我们可以在jquery.validate源码中去捕获.打开jquery.validate源文件,找到如下部份,在底部添加捕获异常代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//935左右
                 $.ajax($.extend( true , {
                     url: param,
                     mode: "abort" ,
                     port: "validate" + element.name,
                     dataType: "json" ,
                     data: data,
                     success: function (response) {
                         validator.settings.messages[element.name].remote = previous.originalMessage;
                         var valid = response === true ;
                         if ( valid ) {
                             var submitted = validator.formSubmitted;
                             validator.prepareElement(element);
                             validator.formSubmitted = submitted;
                             validator.successList.push(element);
                             validator.showErrors();
                         } else {
                             var errors = {};
                             var message = (previous.message = response || validator.defaultMessage( element, "remote" ));
                             errors[element.name] = $.isFunction(message) ? message(value) : message;
                             validator.showErrors(errors);
                         }
                         previous.valid = valid;
                         validator.stopRequest(element, valid);
                     }
                     //添加捕获异常部分(959行左右)
                     ,error: function (a,b,c){
                         alert(b + " " + c) ;
                     }
                 }, param));

保存后,重新测试,如下结果:

jquery.validate 1.7版本(remote方法)bug修复方法(二)_第4张图片

这是一个类型转换错误,重新检查一下jquery.validate ajax部份源份,发现一个奇怪的地方:

?
1
2
3
4
5
$.ajax($.extend( true , {
     url: param,
     mode: "abort" ,
     port: "validate" + element.name,
     dataType: "json" ,

       看dataType参数部份,作者已经将服务端响应格式固定为json格式.同时查阅官方remote 文档,其中对返回值部份解释的很模糊,虽然强调了返回值应该为json格式,但也提到使用true, false, 或着一个字符串,undefined做为返回,这与dataType:json有冲突.

jquery.validate 1.7版本(remote方法)bug修复方法(二)_第5张图片

  为了确定该冲突是否存在,使用firebug做了一些测试,分别在如下部份打断点:

  1.      jquery.validate.js源文件, 935行,951
  2.      jquery.1.51.js源文件 6564行

jquery.validate 1.7版本(remote方法)bug修复方法(二)_第6张图片

jquery.validate 1.7版本(remote方法)bug修复方法(二)_第7张图片

会依次命中 935,6564,(951暂不会命中).

       其中在命中6564行时,我们可以确定服务端响应正常,同时在此处发生类型转换错误,抛出异常.该异常正是我们在jquery.validate 源码中捕获的那个异常.

     因为服务端返回的是true或者false,是文本格式,因此我们将jquery.validate源文件中,dataType的json类型改为text,如下:

jquery.validate 1.7版本(remote方法)bug修复方法(二)_第8张图片

我们再次测试,已经没有错误了,此时在success方法中打断点能够命中.如图:

jquery.validate 1.7版本(remote方法)bug修复方法(二)_第9张图片

     如代码  var valid = response === true; response 为字符型, valid会永远为false.做如下修改:

?
1
2
validator.settings.messages[element.name].remote = previous.originalMessage;
var valid = response == "true" ;

    此时,验证一个合法邮箱的逻辑测试结果正常.我们再来看看不合法邮箱提示:

jquery.validate 1.7版本(remote方法)bug修复方法(二)_第10张图片

直接输出false了,此时951处断点命中了

优先使用不合法

在知道输出false的原因了后,我们再把服务端做如下修改:

?
1
2
3
4
5
6
7
8
9
10
11
12
public void ProcessRequest (HttpContext context) {
         context.Response.ContentType = "text/plain" ;
         string key = context.Request[ "key" ];
         if (key == "[email protected]" )
         {
             context.Response.Write( "该邮箱已存在" );
         }
         else
         {
             context.Response.Write( "true" );
         }
     }

  此时非法提示结果:

jquery.validate 1.7版本(remote方法)bug修复方法(二)_第11张图片

    写到此外,jquery.validate的remote方法修复过程完成了.

      当然大家或许也有疑问,例如在messages中remote 提示信息岂不是多余了. 这个取决于使用者的偏好.如果大家和作者想法一样,希望在服务端提示非法原因.那就不用修改了.如下是客户端控置remote异常提示的修改方法:

?
1
2
//var message = (previous.message = response || validator.defaultMessage( element, "remote" ));
   var message =  validator.defaultMessage( element, "remote" );

你可能感兴趣的:(validate)