jQuery1.4与1.3序列化致使URL参数名有中括号问题(相同参数名、数组参数名)

本文为原作希望转载标明出处和作者!

jQuery从1.3更新到1.4,做了很大的改变,尤其是DOM操作性能,元素事件和属性的操作适用性、可操作性,都有大大的提升。最近项目需要用要JQ,所以选用了1.4版本的。不过在做AJAX请求过程中出现了让从莫明其妙的的一个问题。就是序列化后形成的URL中的参数名出现了中括号,甚是惊奇。于是用FF的debug插件工具,进行跟进才发现,不管怎么处理,只要是数据参数(具有相同参数名的参数)都会加上中括号,这下麻烦了。。。

我需要传递一个数组形式的的参数给一个servlet处理,例如(示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    $.ajax({
	//traditional: true,
        type: "POST",
        url: "saveDetectInfo.do",
        data: {
            JSESSIONID: $("body").attr("JSESSIONID"),
            t: new Date(),
            test: ["test1","test2"]
        },
        timeout: 3 * 60 * 1000,
        dataType: "script",
        error: function(){
            alert("请求异常");
        },
        success: function(){
            //alert("请求成功");
        }
    });

在传到servlet后debug,发现parameterMap里的值如下:

{test[]=[Ljava.lang.String;@8aaff4, JSESSIONID=[Ljava.lang.String;@125d92c}

很明显,HttpServletRequest 对象返回的参数名有:test[] ,JSESSIONID,很明显,我们需要的是test参数名,这是为什么呢?经过查阅JQ官方文档才得知,JQ1.4和1.3的序列化结果和处理方式不一样:

详细见:http://api.jquery.com/jQuery.param/

1
2
3
4
5
6
7
8
9
10
 
// < =1.3.2: 
$.param({ a: [2,3,4] }) // "a=2&a=3&a=4"
// >=1.4:
$.param({ a: [2,3,4] }) // "a[]=2&a[]=3&a[]=4"
 
// < =1.3.2: 
$.param({ a: { b:1,c:2 }, d: [3,4,{ e:5 }] }) // "a=[object+Object]&d=3&d=4&d=[object+Object]"
// >=1.4: 
$.param({ a: { b:1,c:2 }, d: [3,4,{ e:5 }] }) // "a[b]=1&a[c]=2&d[]=3&d[]=4&d[2][e]=5"

难道JQ1.4就没有办法处理吗?于是我拿来源码,跟踪分析在JQ.param方法中有个参数traditional,它是设置是否使用传统的序列化方式,也就是支持<=1.3.2,然后在去查API,在ajax请求中有traditional这个参数。即把示例中的{//traditional: true,}的注释去掉就可以了。然后再跟踪进到servlet中去查看parameterMap的值,结果如下:

{JSESSIONID=[Ljava.lang.String;@10ac2a3, t=[Ljava.lang.String;@17082d8, test=[Ljava.lang.String;@19e733e}

这个看到test了吧。而不是test[]了吧?终于看到曙光了。。这里貌似出现了t,而上面没有出现,我不知道为什么,也没有去分析,反正我要的东西出来。这个留看大家来分析啦。

PS:有网友还不知道如何在servlet中获取数据参数。我这里也顺便讲讲。

上面我为什么要test而不是要test[],就是因为它不符合我们的解析要求,但为什么要这样做,这个是为了方便php等其它的开发语言。好了在servlet获取如下:

1
2
3
4
5
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  String jsessionid = request.getParameter("JSESSIONID");
  String[] test1 = request.getParameterValues("test[]");//traditional未设置为true
  String[] test2 = request.getParameterValues("test");//traditional设置为true
}

这下更明白为什么要用traditional了吧,程序员是选择test[]参数名还是愿意选择test参数名呢?不过这为PHP等提供了方便之门,苦了我们JAVA开发都,呵呵~~~~