Ajax实战(6):创建xhr时异常处理
我们在前面几篇文章中一直采用最精简的方式创建的核心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 }();