改造请求参数-Ajax之二

4/25/2011来源:Ajax教程人气:6375

接上篇。引入了一个私有函数_serialize,它会把js对象串行化成HTTP所需参数模式,接受如下两种结构

1 {name:'jack',age:20} --> name=jack&age=20
2 {fruit:['apple','banana','orange']} --> fruit=apple&fruit=banana&fruit=orange

请求后台的一个servlet,发送参数name=jack,age=20,默认使用异步,GET方式。现在data可以如下了

01 Ajax.request('servlet/ServletJSON',{
02         data : {name:'jack',age:20},
03         success : function(xhr){
04             //to do with xhr
05         },
06         failure : function(xhr){
07             //to do with xhr
08         }
09     }
10 );

完整代码

01 Ajax = 
02 function(){
03     function request(url,opt){
04         function fn(){}
05         var async   = opt.async !== false,
06             method  = opt.method    || 'GET',
07             encode  = opt.encode    || 'UTF-8',
08             data    = opt.data      || null,
09             success = opt.success   || fn,
10             failure = opt.failure   || fn;
11             method  = method.toUpperCase(); 
12         if(data && typeof data == 'object'){//对象转换成字符串键值对
13             data = _serialize(data);
14         }
15         if(method == 'GET' && data){
16             url += (url.indexOf('?') == -1 ? '?' : '&') + data;
17             data = null;
18         }
19         var xhr = window.xmlHttpRequest ? new xmlhttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
20         xhr.onreadystatechange = function(){
21             _onStateChange(xhr,success,failure);
22         };
23         xhr.open(method,url,async);
24         if(method == 'POST'){
25             xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;charset=' + encode);
26         }
27         xhr.send(data);
28         return xhr;
29     }
30     function _serialize(obj){
31         var a = [];
32         for(var k in obj){
33             var val = obj[k];
34             if(val.constructor == Array){
35                 for(var i=0,len=val.length;i<len;i++){
36                     a.push(k + '=' + encodeURIComponent(val[i]));
37                 }
38             }else{
39                 a.push(k + '=' + encodeURIComponent(val));
40             }
41         }
42         return a.join('&');
43     }
44     function _onStateChange(xhr,success,failure){
45         if(xhr.readyState == 4){
46             var s = xhr.status;
47             if(s>= 200 && s < 300){
48                 success(xhr);
49             }else{
50                 failure(xhr);
51             }
52         }else{}
53     }
54     return {request:request};
55 }();

这里仅仅是使data可以是对象类型,貌似没啥大用。但如果与表单(form)结合的话还是很有用的。当我们使用form但又想用Ajax方式提交,那么把form中元素序列化成HTTP请求的参数类型是一个费劲的活。这里写个工具函数formToHash,将form元素按键值形式转换成对象返回

01 function formToHash(form){
02     var hash = {}, el;
03     for(var i = 0,len = form.elements.length;i < len;i++){
04         el = form.elements[i];
05         if(el.name == "" || el.disabled) continue;
06         switch(el.tagName.toLowerCase()){
07         case "fieldset":
08             break;
09         case "input":
10             switch(el.type.toLowerCase()){
11             case "radio":
12                 if(el.checked)
13                     hash[el.name] = el.value;
14                 break;
15             case "checkbox":
16                 if(el.checked){
17                     if(!hash[el.name]){
18                         hash[el.name] = [el.value];
19                     }else{
20                         hash[el.name].push(el.value);
21                     }
22                 }
23                 break;
24             case "button":
25                 break;
26             case "image":
27                 break;
28             default:
29                 hash[el.name] = el.value;
30                 break;
31             }
32             break;
33         case "select":
34             if(el.multiple){
35                 for(var j = 0, lens = el.options.length;j < lens; j++){
36                     if(el.options[j].selected){
37                         if(!hash[el.name]){
38                             hash[el.name] = [el.options[j].value];
39                         }else{
40                             hash[el.name].push(el.options[j].value);
41                         }
42                     }
43                 }
44             }else{
45                 hash[el.name] = el.value;
46             }
47             break;
48         default:
49             hash[el.name] = el.value;
50             break;
51         }
52     }
53     form = el = null;
54     return hash;
55 }