Ajax之二:改造请求参数

网络整理 - 07-26

接上篇。引入了一个私有函数_serialize,它会把对象串行化成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  .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  }