简单实现jQuery 风格的 Ajax

Ajax 已经是一个很老的话题了,现在各种框架都会有成熟的封装,使得开发人员可以以较低的学习成本就可以熟练的创建基于ajax技术的应用。

这里面的缺点也很明显,相当一部分开发人员对ajax底层的知识了解甚少,如果脱离框架,可能就会不知所措————

当然,这种情形一般不会发生在开发过程中,更多的出现在面试过程中~ 大家都懂。

看一百遍不如自己实现一遍,动手之前建议参考一下 w3cschool 的 AJAX 教程 简单基础实用。

今天要实现的是 模仿 jQuery 风格的 ajax 调用方式:

$.get(url,[data],[callback]);
$.post(url,[data],[callback]);

最终完成的目标是像这样发起异步请求并且处理返回数据:

Ajax.get('get.php',{foo:'bar'},function(data){
		onGet(data);
		});


Ajax.post('post.php',{pre:'huvtx',last:'ZHONGWEN中文@##@太热teshuf'},function(data){
		onPost(data);
		});

开始动手,动手之前先思考一下代码如何组织 思考完了:

var Ajax = Ajax || {};

Ajax = (function(){
	//如果有jQuery 的 ajax实现就直接用jQuery.ajax 	
	if(window.jQuery && jQuery.ajax) return jQuery.ajax; 
	
	/*
	*没有,还是用熟悉的单例模式完成对Ajax对象的配置
	*xhrs 用来存放每次调用建立的xhr 对象,xhr不需要复用
	*/
	var it = {}, win = window, doc = document ,  xhrs = {};
	
	it.createXhr = function(){
		/*
		*产生一个兼容大部分浏览器的XMLHttpRequest 对象
		*return xhr;
		*/
		};
	
	it.getXhr = function(t){
		/*
		*按照调用时间生成一个xhr对象 并存到 xhrs 中去
		*需要调用 it.createXhr
		*return xhrs[t];
		*/
		};	
	
	it.dataQuest = function(data){
		/*
		*将 data 对象转换为字符串 
		*{foo:bar,foo2:bar2} => foo=bar&foo2=bar2
		*如果传进来的是字符串 保持原样
		*return string;
		*/
		};	
		
	it.mixUrl = function(url,query){
		/*
		*把url 和 quest 链接起来
		*return url;
		*/
		};	
		
	it.request = function(method, url, data, callback, async){
		/*
		*创建一个xhr 并发送一个请求
		*method string [GET]|[POST]
		*url string 
		*data string|object
		*callback function
		*async true | false true 为异步
		*/
		/*
		*主要几步如下 记不住的话可以简称为 COOS:
		*createXhr open  onreadystatechange send
		*/
		var xhr = it.getXhr(t);
		xhr.open(method, url, syn);
		xhr.onreadystatechange = function(e){ };
		
		/*
		*如果是POST 方式 sentData 需要有值
		*如果想像提交表单一样提交  需要如下设置 requestHeader 
		*如果是GET  方式 sentData 可以不传,或者为 null
		*/
		if(method == 'POST'){
			sentData = quest;
			xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
			};
					
		xhr.send(sentData);	
		
		};
	/*
	*get 方法实现 调用 request方法
	*/
	
	it.get = function(url,data,callback,async){
				
		it.request('GET', url, data, callback, async);
		
		};	
	
	/*
	*post 方法实现 调用 request方法
	*/	
		
	it.post = function(url, data, callback, async){
				
		it.request('POST', url, data, callback, async);
		
		};	
		
	/*
	*清除使用完的xhr 对象
	*/	
	it.clearXhr = function(t){
		if(xhrs[t]){
			xhrs[t].onreadystatuschange = null;			
			xhrs[t] = null;
			}
		};
	/*
	* 简单的trim 用于处理 responseText 
	*/	
	it.trim = function(s){		
		return s.replace(/(^\s*)|(\s*$)/g,'');
		};			
			
	/*
	*配置完成 返回 Ajax 对象
	*/
	return it;
	})();

完整代码:

var Ajax = Ajax || {};

Ajax = (function(){
	var it = {}, win =window , doc = document , xhrs = {};
	
	it.createXhr = function(){
		var xhr = null;
		if(win.XMLHttpRequest){
			try{
				xhr = new XMLHttpRequest()
				}catch(e){
				xhr = null;	
				}
			}else {
				try{
					xhr = new ActiveXObject('Msxml2.XMLHTTP');
					}catch(e){
						try{
							xhr = new ActiveXObject('Microsoft.XMLHTTP');
							}catch(e){
							xhr = null;	
							}
					}
				
				}
		
		return xhr;
		};
		
	it.getXhr = function(t){
				
		if(xhrs[t]) return xhrs[t];
		
		xhrs[t] = it.createXhr();
		
		return xhrs[t];
		};	
	
	
	it.dataQuest = function(data){
		var quest = '';
		if(typeof data == 'string'){
			quest = data;
			}else if(typeof data == 'object'){
				var parms = [];
				for(var o in data){
					parms.push(o+'='+ encodeURIComponent( data[o]));
					};
				quest = parms.join('&');	
			};
			
		return quest;	
		};
	
	it.mixUrl = function(url,query){
		url+= url.indexOf('?') > 0 ? '&' : '?';
		url+= query;			
		return url.replace(/(\?)+/g,'?').replace(/(\&)+/g,'&');	
			
		};	
	
	it.request = function(method, url, data, callback, async){
		
		var t = new Date()*1,
			xhr = it.getXhr(t),
			sentData = null,
			quest = it.dataQuest(data),
			syn = (typeof async == 'undefined') ? true : async;
		
		if(method == 'GET'){
			url = it.mixUrl(url,quest);	
			};
						
		xhr.open(method, url, syn);
		
		
		xhr.onreadystatechange = function(e){
			//alert(xhr.status);
			if(xhr.readyState == 4){
				if(xhr.status >=200 && xhr.status < 400){
					var data = it.trim(xhr.responseText);
						
						if(data && typeof callback == 'function'){							
							callback(data);
							setTimeout(function(){
								it.clearXhr(xhr);
								},0);
							}
					}
				}
			};
		
		if(method == 'POST'){
			sentData = quest;
			xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
			};
			
		xhr.send(sentData);	
		
		};
	
	it.get = function(url,data,callback,async){
				
		it.request('GET', url, data, callback, async);
		
		};	
		
	it.post = function(url, data, callback, async){
				
		it.request('POST', url, data, callback, async);
		
		};
		
	it.clearXhr = function(t){
		if(xhrs[t]){
			xhrs[t].onreadystatuschange = null;			
			xhrs[t] = null;
			}
		};
		
	it.trim = function(s){		
		return s.replace(/(^\s*)|(\s*$)/g,'');
		};			
		
		
	return it;
	})();

调用方法:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>ajax test</title>
<script src="at.js"></script>
</head>

<body>

<script>
	function getTest(){
		Ajax.get('get.php',{foo:'bar'},function(data){
		alert(data);
		})
		};
		
	function postTest(){
		Ajax.post('post.php',{pre:'huvtx',last:'ZHONGWEN中文@##@太热teshuf'},function(data){
		alert(data);
		})
		};
	
	
			
</script>
<button onClick="getTest()">GET</button>
<button onClick="postTest()">POST</button>
</body>
</html>

看看服务端干了些啥:

/*
*get.php 太简陋了
*/

<?php
$foo = $_GET['foo']; 
echo 'your foo is ~'.$foo;
?>

/*
*post.php 更简陋~
*/

<?php 

$pre = $_POST['pre'];
$last = $_POST['last'];

echo $pre.$last;

?>

完~  

最后补充几点相关的文章:

关于GET 和 POST 的区别

 http://www.nowamagic.net/librarys/veda/detail/1919 

不再以讹传讹,GET和POST的真正区别

 网上的多数答案都是错的

http://www.yining.org/2010/05/04/http-get-vs-post-and-thoughts/

从HTTP GET和POST的区别说起

 

  

 

 

  

  

  

posted on 2013-04-26 11:07  trance  阅读(419)  评论(0编辑  收藏  举报

导航