Ajax实战(2):改造请求数

网络整理 - 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 }