Ajax实战(6):创建xhr时异常处理

网络整理 - 07-26

我们在前面几篇文章中一直采用最精简的方式创建的核心XMLHttpRequest对象

1 var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');

没有考虑其可能出现的异常,即创建失败。其实个人认为以上创建方式创建失败的几率非常之少,起码在IE6/7/8/Firefox/Safari/Chrome/Opera如此,其它浏览器就不知了。

但作为一个基础库还是完善下,如果出现创建失败,failure的第二个参数msg将会被赋值为"create xhr failed"。

如下

01 var xhr = function(){

02     try{

03         return new XMLHttpRequest();

04     }catch(e){

05         try{

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

07         }catch(e){

08             try{

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

10             }catch(e){

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

12             }

13         }

14     }

15 }();

完整源码

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 'on':

080                     result = function(str){

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

082                     }(xhr.responseText);

083                     break;

084                 case 'xml':

085                     result = xhr.responseXML;

086                     break;

087             }

088             success(result);

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

090             failure(xhr,'request timeout'); 

091         }else{

092             failure(xhr,xhr.status);

093         }

094         xhr = null;

095     }

096     return (function(){

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

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

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

100                 return function(url,opt){

101                     opt = opt || {};

102                     opt.type = types[i];

103                     return request(url,opt);

104                 }

105             }(i);

106         }

107         return Ajax;

108     })();

109 }();