Ajax基本原理
摘要:本文介绍了Ajax的基本原理,交互过程和与之相关的技术及简单的实现方法,在此基础上给出了一个完整的实例,以使得能够对Ajax有一个更清楚的理解。
关键字:Ajax,JavaScript,DOM,无刷新页面,不完全刷新
引言
计算机桌面应用使我们得以用以前不能想象的方式处理大量的复杂数据;基于计算机网络的C/S模式应用使得共享数据和资源成为现实。然而,正如C/S模式的应用是由于人们不满足单机的桌面应用一样,人们对C/S模式也心存抱怨了:C/S模式除了带给我们数据和资源共享的便利之外,也给我们带来了令我们(程序开发设计人员)和客户头疼的部署和发布问题。于是,B/S模式应用应运而生,而且得到了迅速的发展。B/S模式应用符合一定规范的浏览器作为通用客户端,从而解决了C/S模式中最令人头疼的部署和发布问题。但是,到此并没有结束,B/S虽然解决了应用的部署和发布问题,却因为种种限制,使得应用没有了以前丰富的交互,并且每次与服务器的交互都要完全刷新页面,这是非常糟糕和令人不快的。本文讨论了如何解决页面完全刷新和缺乏交互性的问题,我们用的方法就是――Ajax。
Ajax
那么,Ajax到底是什么呢?Ajax(Asynchronous JavaScript + XML),即异步JavaScript + XML的缩写,这只是最初的观点,最初由Jesse James Garrett创造出来的。但是,Ajax现在的覆盖面已经有了进一步的扩展,把允许浏览器与服务器通信而无需刷新当前页面的技术都涵盖在其中了。
坦率的讲,Ajax并不是什么新鲜玩艺。也就是说,Ajax并不是一种全新的技术,而更像一种技巧,是把过去的几种技术巧妙结合的技巧。真正与Ajax相关的新名词应该是XMLHttpRequest――一个最早在IE 5中出现,最近开始在多数浏览器得到支持的用来实现异步通信的对象。正如前面所说,B/S模式是利用浏览器作为其通用的客户端,所以要想异步通讯成为可能,必须要得到浏览器的支持。如果不是有了浏览器对XMLHttpRequest对象的广泛支持,我们可能不会看到Ajax的今天,更不会看到许多对Ajax的著名应用,如Google Map,Google Suggest,Ta-da List等。
Ajax的处理过程是怎样的呢?下图为Ajax应用的标准处理模式。
数据库 |
XHR |
事件 |
Function callback() {//……} |
服务器资源 |
1 |
2 |
6 |
3 |
5 |
4 |
图 1 标准Ajax处理过程
从图中我们可以看出:由事件触发,创建一个XMLHttpRequest对象,把HTTP方法(Get/Post)和目标URL以及请求返回后的回调函数设置到XMLHttpRequest对象,通过XMLHttpRequest向服务器发送请求,请求发送后继续响应用户的界面交互,只有等到请求真正从服务器返回的时候才调用callback()函数,对响应数据进行处理。
在这个交互过程中,涉及到几种我们不得不提的技术:
1. XHTML和CSS――用来使表现标准化;
2.DOM――动态的修改文档的内容和结构;
3.XML――进行数据的交换和处理;
4.JavaScript――对上述几种技术进行绑定,使其成为协同工作的整体。
Ajax相关技术及基本原理
1.XMLHttpRequest简介
XMLHttpRequest,是我们得以实现异步通讯的根本。最早在IE 5 中以ActiveX组件实现;最近,Mozilla 1.0和Safari 1.2中实现为本地对象。XMLHttpRequest虽然不是W3C标准,但却得到了FireFox、Safari、Opera、Konqueror、IE等绝大多数浏览器的支持。这就使得Ajax有了今天如火如荼的发展。
用XMLHttpRequest进行异步通讯,首先必须用JavaScript创建一个XMLHttpRequest对象实例。创建XMLHttpRequest对象实例的代码清单如下所示:
var xmlHttp;
function createXMLHttpRequest(){
if(window.ActiveXObject){
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if(window.XMLHttpRequest){
xmlHttp = new XMLHttpRequest();
}
}
可以看出,创建XMLHttpRequest对象相当容易。首先,声明一个全局变量xmlHttp用来保存即将创建的XMLHttpRequest对象的引用;然后,在createXMLHttpRequest()方法中完成具体创建工作。因为IE与其他浏览器对XMLHttpRequest 对象的实现方法不同,因此在创建时,通过一个分支语句进行判断。如果window.ActiveXObject调用返回true,则证明为IE浏览器,那么就通过传递“Microsoft.XMLHTTP”给ActiveXObject()来创建XMLHttpRequest对象,否则就把XMLHttpRequest实现为本地JavaScript对象。XMLHttpRequest对象在不同浏览器上的实现是兼容的,所以可以用同样的方法访问XMLHttpRequest的方法和属性。
表 1 标准XMLHttpRequest方法
方 法 | 说 明 |
abort() getAllResponseHeader() getResponseHeader("Header") open("method", "url") send(content) setRequestHeader("header", "value") | 停止当前请求 把HTTP请求的所有响应头部作为键/值对返回 返回指定首部的串值 建立对服务器的调用 向服务器发送请求 把指定首部设置为所提供的值 |
表 2 标准XMLHttpRequest属性
属 性 | 说 明 |
onreadystatechange readyState responseText responseXML status statusText | 每个状态改变都会触发这个事件处理器 请求的状态:0-未初始化,1-正在加载,2-已加载,3-交互中,4-完成 服务器的响应,表示为一个文本字符串值 服务器的响应,表示为一个XML 服务器的HTTP状态码 HTTP状态码的相应文本 |
2.利用XMLHttpRequest对象发送简单请求
创建了XMLHttpRequest对象,并了解了XMLHttpRequest对象的方法和属性之后,让我们来看看怎样利用XMLHttpRequest对象发送简单的请求。利用XMLHttpRequest对象发送简单请求的基本步骤如下:
1) 创建XMLHttpRequest对象实例。
2) 设定XMLHttpRequest对象的回调函数,利用onreadystatechange属性。
3) 设定请求属性:设定HTTP方法(GET或POST);设定目标URL。利用open()方法。
4) 将请求发送给服务器。利用send()方法。
3.利用DOM对服务器响应进行处理
前面已经设置了回调函数,回调函数正是用来处理服务器响应信息的。但是,别忘了我们的最终目的:解决页面完全刷新和缺乏交互性的问题。在服务器对我们的请求信息作出响应后,我们就得实现页面的无缝更新(就是无闪烁的更新信息)。要实现这一点,那么就不得不提到DOM了。
DOM(Document Object Model),文档对象模型,是以面向对象方式描述页面文档的对象模型。DOM中定义了,与平台和语言无关的,用来表示和修改文档所需的对象、以及这些对象的属性和方法。通过DOM,我们可以把页面上的数据和结构抽象成一个树型表示,进而可以通过DOM中定义的属性和方法对文档进行操作,如遍历、编辑等。
这样,服务器相应信息就可以通过DOM的方法和属性,动态的更新到页面的相应节点。
从而使用户感觉不到刷新过程的存在,提高了交互性。
4.一个完整的例子
在这里我们给出一个完整的利用Ajax的实例。实例包含两个文件:Request.htm和Response.xml。通过Request.htm向服务器发送请求,而Response.xml模仿了从服务器返回的响应。两个文件清单如下:
<!--Request.htm----------------------------------------------------------->
<html>
<head>
<title>Ajax应用实例</title>
<script type="text/javaScript">
var xmlHttp;
var requestType="";
function createXMLHttpRequest(){
if(window.ActiveXObject){
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if(window.XMLHttpRequest){
xmlHttp = new XMLHttpRequest();
}
}
function startRequest(theRequestType){
requestType = theRequestType;
createXMLHttpRequest();
xmlHttp.onreadystatechange = handleStateChange;
xmlHttp.open("GET","Response.xml",true);
xmlHttp.send(null);
}
function myCallback(){
if(xmlHttp.readyState==4){
if(xmlHttp.status==200){
if(requestType=="all")
listAll();
else if(requestType=="north")
listNorth();
}
}
}
function listAll(){
var xmlDoc = xmlHttp.responseXML;
var allProvs = xmlDoc.getElementsByTagName("prov");
outputList("all",allProvs);
}
function listNorth(){
var xmlDoc = xmlHttp.responseXML;
var north = xmlDoc.getElementsByTagName("north")[0];
var northProvs = north.getElementsByTagname("prov");
outputList("north",northProvs);
}
function outputList(title,provs){
var out=title;
var currentProv = null;
for(var i=0;i<provs.length;i++){
currentProv = provs[i];
out = out + “<br/>” + currentProv.childNodes[0].nodeValue;
}
document.getElementById(title).innerHTML = out;
}
</script>
</head>
<body>
<h1> Ajax应用实例</h1>
<form action="#">
<input type="button" value="列出所有沿海省市"
cοnclick="startRequest('all');"/>
<div id="all"></div>
<input type="button" value="列出江北沿海省市"
cοnclick="startRequest('north');"/>
<div id="north"></div>
</form>
</body>
</html>
<!--Response.xml---------------------------------------------------------->
<?xml version="1.0"encoding="utf-8" ?>
<provs>
<north>
<prov>辽宁</prov><prov>河北</prov><prov>天津</prov>
<prov>山东</prov><prov>江苏</prov>
</north>
<south>
<prov>浙江</prov><prov>福建</prov><prov>广东</prov>
<prov>广西</prov><prov>海南</prov><prov>上海</prov>
<prov>台湾</prov><prov>香港</prov><prov>澳门</prov>
</south>
</provs>
小结
我们已经了解了Ajax的基本原理和相关的技术。其实,Ajax就是通过JavaScript创建XMLHttpRequest对象,再由JavaScript调用XMLHttpRequest对象的方法完成异步通信;然后,再由JavaScript通过DOM的属性和方法,完成页面的不完全刷新。