Ajax实战(5):处理超时

网络整理 - 07-26

我们在上一文中介绍了如何检查是否超时,超时后却不做任何处理。这里如果超时,会给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 }();