2010年12月18日星期六

一个简单好用的AJAX类,支持超时处理,兼容IE6/IE7/IE8/firefox/chrome/opera(转)

做一回标题党,因为很多人会通过那些关键字搜索进来。是否“简单好用”不太好说,因人而异,但后面两句还是比较靠谱的。


这个AJAX“类”是自己几年前写的,最近抽空整理了一下发出来,供新手或有需要的人参考

在用AJAX的时候,一般只需要关心三个步骤:

1) 请求发送前做什么;

     比如:展现给用户一个loading的图片或文字信息。


2) 发送请求;

     这里有三个参数:url—发送到哪里,data—发送什么数据,method—用什么方式发送数据(GET or POST)


3) 请求返回后做什么;

     比如:将返回后的数据直接或组织成html后插入到页面中展现给用户。


考虑在某些情况下,请求返回的时间很长甚至没有返回,如果一直在loading,恐怕不是一种好的用户体验。所以增加一个在超时的情况下要做的步骤。


由于GET方式经常用,所以单独为它准备了一个方法。


在demo中的test3,除了演示另一种调用方式外,还演示了客户端和服务端之间通过JSON进行通信。


 

最 后面附有完整demo的源代码供下载 <script src="/javascripts/tinymce/themes/advanced/langs/zh.js" type="text/javascript"></script><script src="/javascripts/tinymce/plugins/javaeye/langs/zh.js" type="text/javascript"></script>

Js代码
  1. /*! 
  2. * 一个简单的Ajax类 
  3. * author: ichenshy@gmail.com 
  4. * date:   2010/06/04 Friday 
  5. * 
  6. * @param function fnBefore     用户自定义函数 Ajax开始前执行,若无则为null 
  7. * @param function fnAfter      用户自定义函数 Ajax完成后执行,若无则为null 
  8. * @param function fnTimeout    用户自定义函数 Ajax请求超时后执行,若无则为null 
  9. * @param integer  iTime        设置超时时间 单位毫秒 
  10. * @param boolean  bSync        是否为同步请求,默认为false 
  11. */  
  12.   
  13. function Ajax(fnBefore,fnAfter,fnTimeout,iTime,bSync){  
  14.     this.before     = fnBefore;  
  15.     this.after      = fnAfter;  
  16.     this.timeout    = fnTimeout;  
  17.     this.time       = iTime ? iTime : 10000;  
  18.     this.async      = bSync ? false : true;  
  19.     this._request   = null;  
  20.     this._response  = null;  
  21. }  
  22.   
  23. Ajax.prototype = {  
  24.     /** 
  25.     *  将需要发送的数据进行编码 
  26.     * 
  27.     *  @param object data  JSON格式的数据,如: {username:"fyland",password:"ichenshy"} 
  28.     */  
  29.     formatParam : function( data ){  
  30.         if ( ! data || typeof data != "object" ) return data;  
  31.         var k,r = [];  
  32.         for ( k in data ) {  
  33.             r.push([k,'=',encodeURIComponent(data[k])].join(''));  
  34.         }  
  35.         return r.join('&');  
  36.     },  
  37.   
  38.     /** 
  39.     * 创建 XMLHttpRequest对象 
  40.     */  
  41.     create : function(){  
  42.         if( window.XMLHttpRequest ) {  
  43.             this._request = new XMLHttpRequest();  
  44.         } else {  
  45.             try {  
  46.                 this._request = new window.ActiveXObject("Microsoft.XMLHTTP");  
  47.             } catch(e) {}  
  48.         }  
  49.     },  
  50.   
  51.     /** 
  52.     * 发送请求 
  53.     * 
  54.     * @param string             url     请求地址 
  55.     * @param object or string   data    可以是字符串或JSON格式的数据,如: {username:"fyland",password:"ichenshy"} 
  56.     * @param string             method  请求方式 : GET or POST 
  57.     * @param boolean            ifCache 返回数据是否在浏览器端缓存,默认为false; 
  58.     */  
  59.     send : function(url,data,method,ifCache){  
  60.         if ( typeof this.before == "function" ) this.before();  
  61.   
  62.         method = method.toUpperCase();  
  63.         this.create();  
  64.   
  65.         var self = this;  
  66.         var timer = setTimeout(function(){  
  67.                 if ( typeof self.timeout == "function" ) self.timeout();  
  68.                 if ( self._request ) {  
  69.                     self._request.abort();  
  70.                     self._request = null;  
  71.                 }  
  72.                 return true;  
  73.             },this.time);  
  74.   
  75.         var sendBody  = this.formatParam(data);  
  76.   
  77.         if ( 'GET' == method ) {  
  78.             url = [url, ( url.indexOf('?') == -1 ? '?' : '&') ,sendBody].join('');  
  79.             sendBody = null;  
  80.         }  
  81.   
  82.         if ( ! ifCache ) {  
  83.             url = [url, ( url.indexOf('?') == -1 ? '?' : '&') , "ajaxtimestamp=" , (new Date()).getTime()].join('');  
  84.         }  
  85.   
  86.         this._request.open(method,url,this.async);  
  87.         if ( "POST" == method ) this._request.setRequestHeader("Content-Type""application/x-www-form-urlencoded");  
  88.   
  89.         this._request.onreadystatechange = function(){  
  90.             if( self._request.readyState==4 ){  
  91.                 if ( self._request.status==200 ){  
  92.                     if ( timer ) clearTimeout(timer);  
  93.                     self._response = self._request.responseText;  
  94.                     if ( typeof self.after == "function") self.after(self._response);  
  95.                 }  
  96.             }  
  97.         }  
  98.         this._request.send( sendBody );  
  99.     },  
  100.   
  101.     /** 
  102.     *   简单的GET请求 
  103.     * 
  104.     *   @param string url  请求地址 
  105.     *   @param null or string or object data 
  106.     *   @param object html element or string id   e 
  107.     *   @param string loading                     loading时在e中的显示 
  108.     *   @param boolean  ifCache    浏览器是否缓存 
  109.     */  
  110.     get : function(url,data,e,loading,ifCache){  
  111.             if ( typeof e == "string" ) e = document.getElementById(e);  
  112.             if ( loading ) {  
  113.                 var rg = /\.(gif|jpg|jpeg|png|bmp)$/i;  
  114.                 if ( rg.test(loading) ){  
  115.                     loading = ['<img src="', loading , '"  align="absmiddle" />'].join('');  
  116.                 }  
  117.                 this.before = function(){e.innerHTML = loading;}  
  118.             }  
  119.             this.after      = function(s){e.innerHTML = s;}  
  120.             this.timeout    = function(){e.innerHTML = ' 请求超时! ';}  
  121.             this.send(url,data,"GET",ifCache ? true : false);  
  122.     }  
  123. };  

 

常用调用方式:

Js代码
  1. function test1(){  
  2.      (new Ajax()).get("./process.php?test=1",'',$("view"),"test1正在读取数据……"); // 这里可以传入一个loading的图片地址  
  3. }  
  4.   
  5. function test2(){  
  6.     (new Ajax(function(){  
  7.         $("view").innerHTML = "test2正在读取数据,请稍候";  
  8.     },function(s){  
  9.         $("view").innerHTML = s;  
  10.     },function(){  
  11.         $("view").innerHTML = "Sorry,请求超时!";  
  12.     },5000) ).send("./process.php?test=2",{author:"fyland",mail:"ichenshy@gmail.com",date:"2010-06-03"},"POST");  
  13. }  
  14.   
  15. function test3(){  
  16.     var jx = new Ajax();  
  17.     jx.before = function(){  
  18.         $("view").innerHTML = "test3正在读取数据,请稍候";  
  19.     }  
  20.   
  21.     jx.after = function(s){  
  22.         var r = jsonDecode(s);  
  23.         for ( var k in r ){  
  24.             alert(k + ' : ' + r[k]);  
  25.         }  
  26.         $("view").innerHTML = "test3数据读取完毕";  
  27.     }  
  28.   
  29.     jx.timeout = function(){  
  30.         $("view").innerHTML = "Sorry,TEST3请求超时!";  
  31.     }  
  32.   
  33.     jx.time = 5000;  
  34.   
  35.     var data = {  
  36.                     author: "fyland",  
  37.                     mail  : "ichenshy@gmail.com",  
  38.                     date  : "2010-06-03"  
  39.                 };  
  40.   
  41.     jx.send("./process.php?test=3",data,"GET");  
  42. }  

 


注:
1、method只支持GET和POST
2、ifCache设为false或者不设置,可以控制浏览器不缓存,但设为true后,不一定能控制浏览器缓存返回的数据,因为还需要服务端的配合。

 

  • 大小: 4.6 KB
摘自:http://www.javaeye.com/topic/685578

没有评论: