Ajax实战(5):处理超时
我们在上一文中介绍了如何检查是否超时,超时后却不做任何处理。这里如果超时,会给failure第二个参数msg赋值为“request timeout”。
这样使用者能清楚的知道一次HTTP请求的细节。实现细节较为诡异,慢慢体会。这里timeout的效果和JQuery,Ext是一样的。如下
1 .text('../servlet/Ajax',{
2 timeout : 2000,
3 success : function(result){},
4 failure : function(xhr,msg){
5 alert(msg);
6 }
7 });
完整源码
01 Ajax =
02 function(){
03 function request(url,opt){
04 function fn(){}
05 opt = opt || {};
06 var async = opt.async !== false,
07 method = opt.method || 'GET',
08 type = opt.type || 'text',
09 encode = opt.encode || 'UTF-8',
10 timeout = opt.timeout || 0,
11 data = opt.data || null,
12 success = opt.success || fn,
13 failure = opt.failure || fn;
14 method = method.toUpperCase();
15 if(data && typeof data == 'object'){
16 data = _serialize(data);
17 }
18 if(method == 'GET' && data){
19 url += (url.indexOf('?') == -1 ? '?' : '&') + data;
20 data = null;
21 }
22 var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
23 if(!xhr){return;}
24 var isTimeout = false, timer;
25 if(timeout>0){
26 timer = setTimeout(function(){
27 xhr.abort();
28 isTimeout = true;
29 },timeout);
30 }
31 xhr.onreadystatechange = function(){
32 if (xhr.readyState == 4 && !isTimeout){
33 _onStateChange(xhr, type, success, failure);
34 clearTimeout(timer);
35 }else{}
36 };
37 xhr.open(method,url,async);
38 if(method == 'POST'){
39 xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;charset=' + encode);
40 }
41 xhr.send(data);
42 return xhr;
43 }
44 function _serialize(obj){
45 var a = [];
46 for(var k in obj){
47 var val = obj[k];
48 if(val.constructor == Array){
49 for(var i=0,len=val.length;i<len;i++){
50 a.push(k + '=' + encodeURIComponent(val[i]));
51 }
52 }else{
53 a.push(k + '=' + encodeURIComponent(val));
54 }
55 }
56 return a.join('&');
57 }
58 function _onStateChange(xhr,type,success,failure){
59 var s = xhr.status, result;
60
61 if(s>= 200 && s < 300){
62 switch(type){
63 case 'text':
64 result = xhr.responseText;
65 break;
66 case 'on':
67 result = function(str){
68 return (new Function('return ' + str))();
69 }(xhr.responseText);
70 break;
71 case 'xml':
72 result = xhr.responseXML;
73 break;
74 }
75 success(result);
76 }else if(s===0){
77 failure(xhr,'request timeout');
78 }else{
79 failure(xhr,xhr.status);
80 }
81 xhr = null;
82 }
83 return (function(){
84 var Ajax = {request:request}, types = ['text','json','xml'];
85 for(var i=0,len=types.length;i<len;i++){
86 Ajax[types[i]] = function(i){
87 return function(url,opt){
88 opt = opt || {};
89 opt.type = types[i];
90 return request(url,opt);
91 }
92 }(i);
93 }
94 return Ajax;
95 })();
96 }();