Ajax实战(7):新API解析JSON

网络整理 - 07-26

这是我们实战系列的最后一篇。

ECMAScript 5发布有段时间了,其中就包括了解析ON的原生API-JSON.parse。许多浏览器已经支持了。主流JS库如JQuery,Ext,Prototype都优先使用JSON.parse,不支持该方法的浏览器则使用new Function或eval。 为何优先使用JSON.parse,我想一个就是性能,原生的总是要快一些吧。此外JSON.parse较eval也更安全。


这里也当然不能落后了,优先使用JSON.parse,不行再用new Function方式。最后失败了会给failure的第二个参数msg赋值为"parse json error"

01 result = function(str){

02     try{

03         return JSON.parse(str);

04     }catch(e){

05         try{

06             return (new Function('return ' + str))();

07         }catch(e){

08             failure(xhr,'parse json error',e);

09         }

10     }

11 }(xhr.responseText);


完整源码

001 Ajax =

002 function(){

003     function request(url,opt){

004         function fn(){}

005         opt = opt || {};

006         var async   = opt.async !== false,

007             method  = opt.method    || 'GET',

008             type    = opt.type      || 'text',

009             encode  = opt.encode    || 'UTF-8',

010             timeout = opt.timeout   || 0,

011             data    = opt.data      || null,

012             success = opt.success   || fn,

013             failure = opt.failure   || fn;

014             method  = method.toUpperCase();

015         if(data && typeof data == 'object'){//对象转换成字符串键值对

016             data = _serialize(data);

017         }

018         if(method == 'GET' && data){

019             url += (url.indexOf('?') == -1 ? '?' : '&') + data;

020             data = null;

021         }   

022         var xhr = function(){

023             try{

024                 return new XMLHttpRequest();

025             }catch(e){

026                 try{

027                     return new ActiveXObject('Msxml2.XMLHTTP');

028                 }catch(e){

029                     try{

030                         return new ActiveXObject('Microsoft.XMLHTTP');

031                     }catch(e){

032                         failure(null,'create xhr failed',e);

033                     }

034                 }

035             }

036         }();

037         if(!xhr){return;}

038         var isTimeout = false, timer;

039         if(async && timeout>0){

040             timer = setTimeout(function(){

041                 xhr.abort();

042                 isTimeout = true;

043             },timeout);

044         }

045         xhr.onreadystatechange = function(){

046             if (xhr.readyState == 4 && !isTimeout){

047                 _onStateChange(xhr, type, success, failure);

048                 clearTimeout(timer);

049             }else{}

050         };

051         xhr.open(method,url,async);

052         if(method == 'POST'){

053             xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;charset=' + encode);

054         }

055         xhr.send(data);

056         return xhr;

057     }

058     function _serialize(obj){

059         var a = [];

060         for(var k in obj){

061             var val = obj[k];

062             if(val.constructor == Array){

063                 for(var i=0,len=val.length;i<len;i++){

064                     a.push(k + '=' + encodeURIComponent(val[i]));

065                 }               

066             }else{

067                 a.push(k + '=' + encodeURIComponent(val));

068             }               

069         }

070         return a.join('&');

071     }

072     function _onStateChange(xhr,type,success,failure){

073         var s = xhr.status, result;

074         if(s>= 200 && s < 300){

075             switch(type){

076                 case 'text':

077                     result = xhr.responseText;

078                     break;

079                 case 'json':

080                     

081                     result = function(str){

082                         try{

083                             return JSON.parse(str);

084                         }catch(e){

085                             try{

086                                 return (new Function('return ' + str))();

087                             }catch(e){

088                                 failure(xhr,'parse json error',e);

089                             }

090                         }

091                     }(xhr.responseText);

092                 break;

093                 case 'xml':

094                     result = xhr.responseXML;

095                     break;

096             }

097             // text, 返回空字符时执行success

098             // json, 返回空对象{}时执行suceess,但解析json失败,函数没有返回值时默认返回undefined

099             typeof result !== 'undefined' && success(result);

100               

101             //请求超时,调用abort后xhr.status为0,但不知为0时是否还有其它的情况 

102         }else if(s===0){

103             failure(xhr,'request timeout');

104         }else{

105             failure(xhr,xhr.status);

106         }

107         xhr = null;

108     }

109     return (function(){

110         var Ajax = {request:request}, types = ['text','json','xml'];

111         for(var i=0,len=types.length;i<len;i++){

112             Ajax[types[i]] = function(i){

113                 return function(url,opt){

114                     opt = opt || {};

115                     opt.type = types[i];

116                     return request(url,opt);

117                 }

118             }(i);

119         }

120         return Ajax;

121     })();

122 }();