Ajax应用程序中,XmlHttpRequest对象负责将用户信息以异步通信地发送到服务器端,并接收服务器返回的响应信息和数据。
Javascript本身并未具备向服务器发送请求的能力,要么使用window.open()方法重新打开一个页面向服务器提交请求,要么使用XMLHttpRequest对象发送请求。不同的是,前者是普通的即同步交互模式,而后者是异步交互方式。
XMLHttpRequest提供了一系列的属性和方法,来向服务器发送异步的http请求;在服务器处理用户请求的过程中,XMLHttpRequest通过属性的状态值来实时反映http求所处的状态,并根据这些状态指示Javascript做相应的处理;当服务器顺利完成响应用户行为的动作、并将响应数据返回时,XMLHttpRequest提供的response系列方法,可以将这些响应数据以文本、XML Document对象、Ado Stream对象或者unsigned byte数组的方式组装起来,提供给Javascript处理。

4.6.2  XMLHttpRequest对象的属性和方法

IE5.0开始,开发人员可以在Web页面内部使用XMLHTTP ActiveX组件扩展自身的功能,不用从当前的Web页面导航就可以直接将数据传输到服务器或者从服务器接收数据。Mozilla1.0以及NetScape7则是创建继承XML的代理类XMLHttpRequest;对于大多数情况,XMLHttpRequest对象和XMLHttp组件很相似,方法和属性类似,只是部分属性不同。例程4-25的代码段显示了如何在IE浏览器和Mozilla浏览器中创建XMLHttp- Request对象。
例程4-25  创建XMLHttpRequest对象
<script language="javascript">
var http_request = false;
//IE 浏览器
http_request = new ActiveXObject("Msxml2.XMLHTTP");
http_request = new ActiveXObject("Microsoft.XMLHTTP");
//Mozilla 浏览器
http_request = new XMLHttpRequest();
</script>
不同版本的IE浏览器采用不同方式创建XMLHttpRequest对象,某些旧版本使用Microsoft.XMLHTTP,而较新的版本则使用Msxml2.XMLHTTP。通常,为了保证Ajax程序的浏览器兼容性,需要注意创建XMLHttpRequest对象的程序,要同时支持这两种创建方式。
XMLHttpRequest对象提供了一系列属性和方法,来向服务器发起异步http请求,监听服务器的状态,并在服务器完成数据响应处理之后接收服务器返回的信息数据。表4-17列出了XMLHttpRequest对象的属性。
4-17  XMLHttpRequest对象属性
   
   
onreadystatechange
指定当readyState属性改变时的事件处理句柄,属性为只写
readyState
返回当前请求的状态,属性为只读
responseBody
将回应信息正文以unsigned byte数组形式返回,属性为只读
responseStream
Ado Stream对象的形式返回响应信息,属性为只读
responseText
以字符串的形式返回服务器响应信息,属性为只读
responseXML
将响应信息格式化为XML Document对象返回,属性为只读
status
返回当前HTTP请求的状态码,属性为只读。如:404 = "文件未找到" 200 =
"成功"
statusText
返回当前HTTP请求的状态行,属性为只读
XMLHttpRequest对象属性readyState返回当前XMLHttp请求的状态,这些状态用长度为4的×××数据表示,其属性的状态含义如表4-18所示:
 
4-18  readyState属性的状态
 
   
   
0
未初始化
对象已经建立,但是未初始化,即尚未调用open方法创建http请求
1
初始化
对象已经建立,但是为调用send方法发送http请求
2
发送数据
send方法已经被调用,但是当前的状态以及http头未知
3
数据传送中
已经接收部分数据,因为响应及http头不全,这是通过response系列方法获取部分数据会出现错误
4
传送完成
数据接收完毕,此时可以通过response系列方法获取完整的回应数据
XMLHttpRequest对象属性onreadystatechangereadyState状态改变的事件触发器,用来指定当readyState属性发生改变时的处理事件。在使用过程中,通常通过将事件处理函数名称赋予onreadystatechange的方式,来为XMLHttpRequest指定事件触发器,而在事件处理函数中判断readyState状态值并做相应的处理。例程4-26的代码段指定doState- ReadyHandler函数作为事件处理函数,并在doStateReadyHandler函数体内在readyState状态为4时弹出一个显示“完成”信息的对话框。
例程4-26  指定XMLHttpRequest对象的回调函数
var http_request = null;
http_request = new ActiveXObject("Msxml2.XMLHTTP");
 
function send() {
http_request.onreadystatechange = doStateReadyHandler;
http_request.open("GET","http://localhost/sample.xml",true);
http_request.send();
}
 
function doStateReadyHandler() {
     if(http_request.readySatate==4) window.alert("完成");
}
XMLHttpRequest对象属性responseText将响应信息以字符串的形式返回。XMLHttp- Request尝试将响应信息解码为Unicode字符串,默认的响应数据编码方式为UTF-8。如果服务器返回的数据带有BOMbyte-order mark),则XMLHttpRequest可以解码任何的UCS-2或者UCS-4数据。如果服务器返回的是XML文档,此属性不处理XML文档中的编码声明,仅将整个XML文档作为字符串返回。
如果服务器以XML文档的格式返回响应数据,这时应该采用responseXML属性加以处理。如果响应数据不是有效的XML文档,此属性本身不返回XMLDOMParseError,可以通过处理过的DOMDocument对象获取错误信息。在使用responseXML将服务器响应数据以XML文档的形式返回之前,先要将响应的内容类型设置为application/xml
XMLHttpRequest对象属性status代表当前http请求的状态,为长整型数据。其值及其含义如表4-19所示。
4-19  http请求状态及其含义
   
   
100
客户必须继续发出请求
404
没有发现文件、查询或URl
101
客户要求服务器根据请求转换HTTP协议版本
405
用户在Request-Line字段定义的方法不允许
200
交易成功
406
根据用户发送的Accept拖,请求资源不可访问
201
提示知道新文件的URL
407
类似401,用户必须首先在代理服务器上得到授权
202
接受和处理、但处理未完成
408
客户端没有在用户指定的饿时间内完成请求
203
返回信息不确定或不完整
409
对当前资源状态,请求不能完成 
204
请求收到,但返回信息为空
410
服务器上不再有此资源且无进一步的参考地址
205
服务器完成了请求,用户代理必须复位当前已经浏览过的文件
411
服务器拒绝用户定义的Content-Length属性请求
206
服务器已经完成了部分用户的GET请求
412
一个或多个请求头字段在当前请求中错误
300
请求的资源可在多处得到
413
请求的资源大于服务器允许的大小
301
删除请求数据
414
请求的资源URL长于服务器允许的长度
302
在其他地址发现了请求数据
415
请求资源不支持请求项目格式
303
建议客户访问其他URL或访问方式
416
请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
304
客户端已经执行了GET,但文件未变化
417
服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求
305
请求的资源必须从服务器指定的地址得到
500
服务器产生内部错误
307
申明请求的资源临时性删除
501
服务器不支持请求的函数
400
错误请求,如语法错误
502
服务器暂时不可用,有时是为了防止发生系统过载
401
请求授权失败
503
服务器过载或暂停维修
402
保留有效ChargeTo头响应
504
关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长
403
请求不允许
505
服务器不支持或拒绝支请求头中指定的HTTP版本
在这些状态中,最常用到的是“404”。通常,在类似例子4-20doStateReady Handler的事件处理函数中,判断status的状态,然后做相应的处理。
XMLHttpRequest对象提供了包括sendopen在内的六种方法,用来向服务器发送http请求,并设置相应的头信息。表4-20列出XMLHttpRequest对象提供的方法及其含义。
4-20  XMLHttpRequest对象的方法及其含义
   
   
abort
取消当前请求
getAllResourceHeaders
获取相应的全部http头信息
getResourceHeader
从响应信息中获取指定的http头信息
open
创建一个新的http请求,并指定此请求的方法、URL、以及验证信息(用户名/密码)
send
发送请求到http服务器并接收回应
setRequestHeader
单独设定请求的某个http
abort的语法为:http_request.abort();调用此方法,当前请求返回UNINITIALIZED状态。
方法getAllResourceHeadersJSP中的HttpServletRequest对象一样,获取http请求的请求头信息。其语法为:headers = http_request.getAllResourceHeaders();
相对,getResourceHeader方法则是获取某个指定的http头信息,传入的参数为这个头信息的名称,其语法为:header = http_request.getResourceHeader(“header-name”);
getAllResourceHeadersgetResourceHeader这两种方法,必须等到http请求发送成功即send方法成功执行之后才能够执行,否则会报错。
例程4-27使用getAllResourceHeadersgetResourceHeader两种方法取得相应的头信息,并将这些信息以弹出对话框的形式显示出来。其执行效果如图4-23所示。
XMLHttpRequest对象与Ajax_职场
4-23  获取http请求头信息
例程4-27  sample4_21.htm
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Ch04--获取请求头信息</title>
<script language="javascript">
     var http_request = false;
     function send_request() {//初始化、指定处理函数、发送请求的函数
          http_request = false;
          //开始初始化XMLHttpRequest对象
          if(window.XMLHttpRequest) { //Mozilla 浏览器
               http_request = new XMLHttpRequest();
               if (http_request.overrideMimeType) {//设置MiME类别
                     http_request.overrideMimeType('text/xml');
               }
          }
          else if (window.ActiveXObject) { // IE浏览器
               try {
                    http_request = new ActiveXObject("Msxml2.XMLHTTP");
               } catch (e) {
                     try {
                         http_request = new ActiveXObject("Microsoft. XMLHTTP");
                    } catch (e) {}
               }
          }
          if (!http_request) { // 异常,创建对象实例失败
               window.alert("不能创建XMLHttpRequest对象实例.");
               return false;
          }
          // 确定发送请求的方式和URL以及是否异步执行下段代码
          http_request.open("GET","sample4_19.htm", false);
          http_request.send(null);
          window.alert("全部头信息如下:\n"+http_request.getAll Response Headers() +
               "\n"+"头信息编码类型:\n"+http_request.getResponseHeader ("Content-Type"));
     }
</script>
</head>
 
<body>
<input type="button" name="button" value="显示头信息" onClick="send_ request()">
</body>
</html>
XMLHttpRequest对象的open方法用来新建一个http请求,并设置请求的方法、URL以及验证信息等。其具体语法为:
http_request.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword);
bstrMethod代表http方法,可选值为POSTGETPUTPROPFIND,大小写不敏感。bstrUrl为请求的目标URL地址,可以是绝对地址也可以是相对地址。varAsync为布尔型参数,指定该请求是否为异步方式,默认为true;如果为真,当state状态改变时会调用onreadystatechange属性指向的回调函数。如果服务器需要验证,则应该指定bstrUser参数为要验证的用户名,bstrPassword参数为要验证的密码。如果bstrUserbstrPassword参数不指定,则在服务器需要验证的时候,会弹出验证对话框。
创建http请求之后,就可以向服务器发送http请求,send方法被调用,其语法为:
http_request.send(varBody);
参数varBody为要发送给服务器的内容。如果没有内容要发送,varBody参数可以省略。此方法的同步或异步方式取决于 open 方法中的 varAsync 参数,如果 varAsync False此方法将会等待请求完成或者超时时才会返回,如果varAsyncTrue,此方法将立即返回。如果发送的数据为BSTR,则回应被编码为UTF-8,必须在适当位置设置一个包含charset的文档类型头。如果发送的数据为XML DOM object,则回应将被编码为在xml文档中声明的编码,如果在xml文档中没有声明编码,则使用默认的UTF-8
Ajax应用程序中,有两种方法可以向服务器发送请求内容。一种是以“&内容名称=内容值”的形式直接附加在目标URL后面,通过open()方法设置发送内容。另外一种是将要发送的内容作为send()方法的参数,内容名称及其值也是成对出现的,中间用&字符隔开。

4.7  小结

本章介绍了Ajax用到的几种技术,包括HTMLXMLXHTMLCSSJavascriptDOMXMLHttpRequest对象等等。这些技术各司其职,相互配合,在Ajax应用程序中各自都扮演着重要角色。
HTMLWWW的描述性语言,是Web页面的载体。其允许网页设计人员创建文本与图像相结合的页面,这些页面能够被网上任何人通过浏览器浏览到。HTML作为Web页面的载体,负责向浏览器客户端显示信息数据,构建Web应用程序的用户界面。
XML文档允许Web应用程序开发人员创建自定义标记,以便更有效地组织和传递内容的语言。XML文档因其简洁高效,能够用纯文本的形式表现各种复杂的有层次的数据及其之间的相互关系,易于在各个平台下构造和解析,因此特别适用于数据交换、结构化数据存储与显示、内容呈现与显示格式分离等方面。其在Ajax应用程序中通常作为数据传输或者存储的媒介。
XHTML作为HTML的一种有效补充或者替代,在如今的Web应用程序信息呈现方面发挥了越来越重要的作用。XHTML其实是XML文档的另外一种表现形式,是XMLHTML的结合,有效地继承了XMLHTML各自的有点,使Web应用程序的用户界面呈现更加规范。相对于HTMLXHTML则具备严格的语法约束,更容易与XML文档结合,更易解析。
Javascript作为Web应用程序的脚本语言,在Ajax应用程序中起着“承前启后”的作用。Javascript能够与HTML表单进行交互,对文档中某个表单的输入元素的值进行读写操作。Javascript能够定义事件处理器,在特定的事件发生时指定相应的函数处理用户事件响应,比如鼠标单击、鼠标双击、焦点获取等。Javascript使Ajax应用程序能够像桌面应用程序一样,具备事件触发和响应的能力。
DOMHTML/XHTML/XML文档进行了封装,以树状结构解析HTML/XHTML/ XML文档,使Javascript能够读取和设置文档的信息。其提供了一系列的属性、方法和API,使Javascript能够遍历整个HTML/XHMTL/XML文档,精确定位到文档的某一个节点,读取节点的属性及其内容。DOM技术是学习Ajax应用的重点和难点。
前面说到,Ajax采用异步方式与服务器交互。这种异步通信方式是XMLHttpRequest对象的独特之处。XMLHttpRequest对象提供了一系列的属性,来反映http请求的状态,监听服务器的响应进度。XMLHttpRequest对象的opensend方法,能够将浏览器客户端的信息内容以异步方式提交到服务器,并监听服务器的响应返回,在必要的时候读取或设置http请求头信息。在服务器响应完毕之后,XMLHttpRequest对象能够回调响应的处理函数,使得Javascript操纵DOM更新Web页面内容。
Ajax是一项综合的技术。要对其有足够的了解、熟悉和掌握,除了依赖于开发人员的开发经验之外,对其所用到的基础技术的掌握也是一个重要的环节。本章仅对Ajax常用到的部分基础技术进行阐述,其余部分可以参考相关参考资料。