zoukankan      html  css  js  c++  java
  • 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">
      
    <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 == "abc@qq.com")
            {
                context.Response.Write("false");
            }
            else
            {
                context.Response.Write("true");
            }
        }
       
        public bool IsReusable {
            get {
                return false;
            }
        }
      
    }

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

    QQ截图未命名

    非空验证正常,再来测试remote验证,输入cdf@qq.com,点击提交,如下结果

    邮箱测试

    没有任何反应,我们尝试检测抛出的异常,因为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源码中去捕获.打开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 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有冲突.

    remote解释

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

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

    jquery.validate断点

    jquery.js断点

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

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

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

    json改为text

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

    全等提示

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

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

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

    false

    直接输出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 == "abc@qq.com")
            {
                context.Response.Write("该邮箱已存在");
            }
            else
            {
                context.Response.Write("true");
            }
        }

      此时非法提示结果:

    服务端输出不合法原因

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

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

    1
    2
    //var message = (previous.message = response || validator.defaultMessage( element, "remote" ));
      var message =  validator.defaultMessage( element, "remote" );
  • 相关阅读:
    一致性哈希的理解与实践
    nil in Go
    为什么Go没有math.Min/Max(int, int) 函数?
    What happens when I type kubectl run?
    kubelet简要分析
    编译安装nginx和模块
    nginx与tengine添加check模块(nginx_upstream_check_module)
    多台ESXI 6.5 添加 iSCSI 共享存储 --centos 7.4 作为target
    Cannot open the disk '/vmfs/volumes/5e97f429-a56d6ea0-1ef3-000c29a09445/oracle_node1/oracle_node1_1.vmdk' or one of the snapshot disks it depends on.
    RabbitMQ windows2016 镜像模式 haproxy+keepalived
  • 原文地址:https://www.cnblogs.com/aaa6818162/p/2297339.html
Copyright © 2011-2022 走看看