在经典的浏览器与服务器的交互方式中,由用户触发一个 H TTP 请求到服务器, 服务器对其进行处理后再返回一个新的web页到浏览器,每当服务器处理浏览器提交的请求时,客户都只能空闲等待,并且哪怕只是一次只需从服务器端得到很简单的一个数据的交互,都要返一个完整的 web页,造成用户每次都要浪费时间和带宽去重新读取整个页面。
Ajax的工作原理相当于在用户和服务器之间加了—个中间层———Ajax引擎,使用户操作与服务器响应异步化———并不是所有的用户请求都提交给服务器,一些数据验证和处理由 Ajax自己来做而不必交给服务器处理,只有确定需要从服务器读取新数据时再由 Ajax引擎代为向服务器提交请求。在使用 Ajax引擎后,用户从感觉上几乎所有的操作都会很快响应没有页面重载(白屏)的等待。Ajax引擎,实际上是一个比较复杂的 Java Script应用程序, 用来处理用户请求然后根据需要动态读写服务器和更改DOM内容。以前为了使网页能无缝化重构,也就是在页面已经下载完毕后改变页面内容, 开发人员一直通过 Java Script和DOM来实现。但是要使网页真正动态起来,不仅要内 部 的 互 动 , 还 需 要 从 外 部 获 取 数 据 , 在 XMLHttpRequest出现以前, 我们是让用户来输入数据并通过DOM来改变网页内容的, 但现在 X M LH TTPR e-quest可以让我们在不重载页面的情况下读写服务器上的数据,使用户的输入达到最少。下面介绍一下构成 Ajax引擎的几个主要技术及其在 Ajax引擎中所起的作用。
- XMLHttpRequest在 Ajax引擎中的几项技术中XMLHttpRequest是最核心的技术,是 Ajax引擎解决无需刷新整个页面就可以从服务器获取新数据这个问题的关键所在。在 微 软 IE 平 台 下XMLHttpRequest 是 X M L-H TTP 组件一个对象, 它通过允许开发人员在web页面内部使用XMLHTTPActiveX组件扩展自身的功能,开发人员可以不用从当前的web页面导航而直接传输数据到服务器上或者从服务器取数据。这个功能是很重要的,因为它帮助减少了无状态连接的痛苦,它还可以排除下载冗余 web数据的需要,从而提高进程的速度。对于大多数情况,XMLHttpRequest对象和XMLHTTP组件很相似,方法和属性也类似,只是有一小部分属性不支持。
- DOM是给HTML和XML文件使用的一组API。它提供了文件的结构表述,让你可以改变其中的內容及可见物。其本质是建立网页与 Script或程序语言沟通的桥梁。所有 web开发人员可操作及建立文件的属性、方法及事件都以对象来展现(如document 就表"文件本身"这个对象,table对象则代表HTML的表格对象等等)。这些对象可以由当今大多数的浏览器以 Script来取用。一个用HTM L或XHTM L构建的网页也可以看作是一组结构化的数据, 这些数据被封在DOM中,D O M 提供了网页中各个对象的读写的支持。
- JavaScriptJava Script是一在浏览器中大量使用的跨平台编程语言,常被用来做一些网页特效或表单验证。在A jax中 Javascript则是XMLHttpRequest和DOM交互的桥梁和 Ajax引擎工作的主要推动力。Javascript通过调用XMLHttpRequest的属性和方法来获取服务端数据, 然后调用DOM的API来更新web页面的内容。实现整个页面的无刷新更新页面。
Ajax优缺点分析
任何一项技术都具有其固有的优点及缺点,对于它们的优点和缺点的事先的认识, 有利于将来准确地,有效地利用这项技术。根据以上 Ajax的原理和技术背景可以总结出 Ajax有以下优势:
- 减轻服务器的负担因为 Ajax的根本理念是"按需取数据",所以最大可能在减少了冗余请求和响影对服务器空间和带宽造成的负担。同时 Ajax可以把原来需要服务器要做的许多事情放到客户端来做。我们在上网冲浪的时候可以看到大多数网站的很多页面至少 90% 都是一样的,比如:结构、格式、页头、页尾、广告等,所不同的只是一小部分的内容,但每次服务器都会生成所有的页面再返回给客户端,这无形之中是一种浪费,不管是对于用户的时间、带宽、CPU 耗用, 还是对于ISP的高价租用的带宽和空间来说。如果按一页来算,只能几K或是几十K可能并不起眼,但像每天要生成几百万个页面的大ISP来说,可以说是损失巨大的。而 Ajax可以所为客户端和服务器的中间层,来处理客户端的请求,并根据需要向服务器端发送请求,用什么就取什么、用多少就取多少,就不会有数据的冗余和浪费, 减少了数据下载总量,而且更新页面时不用重载全部内容,只更新需要更新的那部分即可,相对于纯后台处理并重载的方式缩短了用户等待时间,也把对资源的浪费降到最低,所以Ajax对于用户和LSP来说是双赢的。
- 刷新更新页面,减少用户实际和心理等待时间。
同时由于Ajax的自身特性,也存在如下缺点:
- Ajax不存在浏览历史,因此无法做到回退操作,当用户误操作之后只能通过刷新界面进行回退。
- 存在跨域问题,Ajax只能在不能跨页面操作。
- 由于Ajax的数据不出现在源码中,因此无法通过爬虫爬取,造成SEO不友好。
XMLHttpRequest方法、属性、对象
<html>
<head>
<title>XMLHTTPRequest对象的说明 DEMO</title>
<script language="javascript" type="text/javascript">
<!--
var xmlhttp;
// 创建一个XMLHTTPRequest对象
function createXMLHTTPRequext(){
if(window.ActiveXObject) {
xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
}
else if(window.XMLHTTPRequest){
xmlhttp = new XMLHTTPRequest();
}
}
function PostOrder(xmldoc)
{
createXMLHTTPRequext();
// 方法:open
// 创建一个新的http请求,并指定此请求的方法、URL以及验证信息
// 语法:oXMLHttpRequest.open(Method, Url, Async, User,Password);
// 参数
// Method
// http方法,例如:POST、GET、PUT及PROPFIND。大小写不敏感。
// Url
// 请求的URL地址,可以为绝对地址也可以为相对地址。
// Async[可选]
// 布尔型,参数指示请求使用应该异步地执行。如果这个参数是 false,请求是同步的,后续对 send() 的调用将阻塞,直到响应完全接收。如果这个参数是 true 或省略,请求是异步的,且通常需要一个 onreadystatechange 事件句柄。
// 属性:onreadystatechange
// onreadystatechange:指定当readyState属性改变时的事件处理句柄
// User[可选]
// 如果服务器需要验证,此处指定用户名,如果未指定,当服务器需要验证时,会弹出验证窗口。
// Password[可选]
// 验证信息中的密码部分,如果用户名为空,则此值将被忽略。
// 备注:调用此方法后,可以调用send方法向服务器发送数据。
xmlhttp.Open("get", "http://localhost/example.htm", false);
// var book = xmlhttp.responseXML.selectSingleNode("//book[@id='bk101']");
// alert(book.xml);
// 语法:oXMLHttpRequest.onreadystatechange = funcMyHandler;
// 如下的例子演示当XMLHTTPRequest对象的readyState属性改变时调用HandleStateChange函数,
// 当数据接收完毕后(readystate == 4)此页面上的一个按钮将被激活
// 备注:此属性只写,为W3C文档对象模型的扩展.
xmlhttp.onreadystatechange= HandleStateChange;
// 方法:send
// 发送请求到http服务器并接收回应
// 语法:oXMLHttpRequest.send(var Body);
// 参数:var Body (欲通过此请求发送的数据。)
// 备注:此方法的同步或异步方式取决于open方法中的bAsync参数,如果bAsync == False,此方法将会等待请求完成或者超时时才会返回,如果bAsync == True,此方法将立即返回。
// 如果发送的数据为BSTR,则回应被编码为utf-8, 必须在适当位置设置一个包含charset的文档类型头。
// 如果发送的数据为XML DOM object,则回应将被编码为在xml文档中声明的编码,如果在xml文档中没有声明编码,则使用默认的UTF-8。
// 方法:getAllResponseHeaders
// 获取响应的所有http头
// 语法:str Value = oXMLHttpRequest.getAllResponseHeaders();
// 备注:每个http头名称和值用冒号分割,并以\r\n结束。当send方法完成后才可调用该方法。
alert(xmlhttp.getAllResponseHeaders());
// 方法:getResponseHeader
// 从响应信息中获取指定的http头
// 语法:str Value = oXMLHttpRequest.getResponseHeader(bstrHeader);
// 备注:当send方法成功后才可调用该方法。
xmlhttp.getResponseHeader("Content-Type");
//将返回字符串"text/xml"。可以使用 getAllResponseHeaders方法获取完整的http头信息。
alert(xmlhttp.getResponseHeader("Content-Type"));
// 输出http头中的Content-Type列:当前web服务器的版本及名称。
document.frmTest.myButton.disabled = true;
// 方法:abort
// 取消当前请求
// 语法:oXMLHttpRequest.abort();
// 备注:调用此方法后,当前请求返回UNINITIALIZED 状态。
// xmlhttp.abort();
// 方法:setRequestHeader
// 单独指定请求的某个http头
// 语法:oXMLHttpRequest.setRequestHeader(bstr Header, bstr Value);
// 参数:bstr Header(字符串,头名称。)
// bstr Value(字符串,值。)
// 备注:如果已经存在已此名称命名的http头,则覆盖之。此方法必须在open方法后调用。
// xmlhttp.setRequestHeader(bstr Header, bstr Value);
}
function HandleStateChange()
{
// 属性:readyState
// 返回XMLHTTP请求的当前状态
// 语法:Value = oXMLHttpRequest.readyState;
// 备注:变量,此属性只读,状态用长度为4的整型表示.定义如下:
// 0 (未初始化) 对象已建立,但是尚未初始化(尚未调用open方法)
// 1 (初始化) 对象已建立,尚未调用send方法
// 2 (发送数据) send方法已调用,但是当前的状态及http头未知
// 3 (数据传送中) 已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误,
// 4 (完成) 数据接收完毕,此时可以通过通过responseBody和responseText获取完整的回应数据
if (xmlhttp.readyState == 4){
document.frmTest.myButton.disabled = false;
// 属性:responseBody
// 返回某一格式的服务器响应数据
// 语法:str Value = oXMLHttpRequest.responseBody;
// 备注:变量,此属性只读,以unsigned array格式表示直接从服务器返回的未经解码的二进制数据。
alert(xmlhttp.responseBody);
// 属性:responseStream
// 以Ado Stream对象的形式返回响应信息
// 语法:strValue = oXMLHttpRequest.responseStream;
// 备注:变量,此属性只读,以Ado Stream对象的形式返回响应信息。
alert(xmlhttp.responseStream);
// 属性:responseText
// 将响应信息作为字符串返回
// 语法:strValue = oXMLHttpRequest.responseText;
// 备注:变量,此属性只读,将响应信息作为字符串返回。XMLHTTP尝试将响应信息解码为Unicode字符串,
// XMLHTTP默认将响应数据的编码定为UTF-8,如果服务器返回的数据带BOM(byte-order mark),XMLHTTP可以解码任何UCS-2 (big or little endian)或者UCS-4 数据。注意,如果服务器返回的是xml文档,此属性并不处理xml文档中的编码声明。需要使用responseXML来处理。
alert(xmlhttp.responseText);
// 属性:responseXML
// 将响应信息格式化为Xml Document对象并返回
// 语法:var objDispatch = oXMLHttpRequest.responseXML;
// 备注:变量,此属性只读,将响应信息格式化为Xml Document对象并返回。如果响应数据不是有效的XML文档,此属性本身不返回XMLDOMParseError,可以通过处理过的DOMDocument对象获取错误信息。
alert("Result = " + xmlhttp.responseXML.xml);
// 属性:status
// 返回当前请求的http状态码
// 语法:lValue = oXMLHttpRequest.status;
// 返回值:长整形标准http状态码
alert(xmlhttp.status);
// 属性:statusText
// 返回当前请求的响应行状态
// 语法:strValue = oXMLHttpRequest.statusText;
// 备注:字符串,此属性只读,以BSTR返回当前请求的响应行状态,此属性仅当数据发送并接收完毕后才可获取。
alert(xmlhttp.statusText);
}
}
//-->
</script>
</head>
<body>
<form name="frmTest">
<input name="myButton" type="button" value="Click Me" οnclick="PostOrder('http://localhost/example.htm');">
</form>
</body>
</html>