全面剖析XMLHttpRequest对象

 

全面剖析XMLHttpRequest对象 javascript

XMLHttpRequest对象是当今全部AJAXWeb 2.0应用程序的技术基础。尽管软件经销商和开源社团如今都在提供各类AJAX框架以进一步简化XMLHttpRequest对象的使用;可是,咱们仍然颇有必要理解这个对象的详细工做机制。

  
1、 引言

   异步JavaScriptXML(AJAX)是一个专用术语,用于实如今客户端脚本与服务器之间的数据交互过程。这一技术的优势在于,它向开发者提供 了一种从Web服务器检索数据而没必要把用户当前正在观察的页面回馈给服务器。与现代浏览器的经过存取浏览器DOM结构的编程代码(JavaScript) 动态地改变被显示内容的支持相配合,AJAX让开发者在浏览器端更新被显示的HTML内容而没必要刷新页面。换句话说,AJAX可使基于浏览器的应用程序 更具交互性并且更相似传统型桌面应用程序。

  GoogleGmailOutlook Express就是两个使用AJAX技术的咱们所熟悉的例子。并且,AJAX能够用于任何客户端脚本语言中,这包括JavaScriptJscriptVBScript

   AJAX利用一个构建到全部现代浏览器内部的对象-XMLHttpRequest-来实现发送和接收HTTP请求与响应信息。一个经由 XMLHttpRequest对象发送的HTTP请求并不要求页面中拥有或回寄一个<form>元素。AJAX中的"A"表明了"异步",这意味着 XMLHttpRequest对象的send()方法能够当即返回,从而让Web页面上的其它HTML/JavaScript继续其浏览器端处理而由服务 器处理HTTP请求并发送响应。尽管缺省状况下请求是异步进行的,可是,你能够选择发送同步请求,这将会暂停其它Web页面的处理,直到该页面接收到服务 器的响应为止。

  微软在其Internet Explorer(IE) 5中做为一个ActiveX对象形式引入了XMLHttpRequest对象。其余的认识到这一对象重要性的浏览器制造商也都纷纷在他们的浏览器内实现了 XMLHttpRequest对象,可是做为一个本地JavaScript对象而不是做为一个ActiveX对象实现。而现在,在认识到实现这一类型的价 值及安全性特征以后,微软已经在其IE 7中把XMLHttpRequest实现为一个窗口对象属性。幸运的是,尽管其实现(于是也影响到调用方式)细节不一样,可是,全部的浏览器实现都具备相似 的功能,而且实质上是相同方法。目前,W3C组织正在努力进行XMLHttpRequest对象的标准化,而且已经发行了有关该W3C规范的一个草案。

  本文将对XMLHttpRequest对象API进行详细讨论,并将解释其全部的属性和方法。

  
2、 XMLHttpRequest对象的属性和事件

  XMLHttpRequest对象暴露各类属性、方法和事件以便于脚本处理和控制HTTP请求与响应。下面,咱们将对此展开详细的讨论。
readyState
属性

   当XMLHttpRequest对象把一个HTTP请求发送到服务器时将经历若干种状态:一直等待直到请求被处理;而后,它才接收一个响应。这样以来, 脚本才正确响应各类状态-XMLHttpRequest对象暴露一个描述对象的当前状态的readyState属性,如表格1所示。

  表格1.XMLHttpRequest对象的ReadyState属性值列表。
java

ReadyState取值node

描述数据库

0编程

描述一种"未初始化"状态;此时,已经建立一个XMLHttpRequest对象,可是尚未初始化。浏览器

1缓存

描述一种"发送"状态;此时,代码已经调用了XMLHttpRequest open()方法而且XMLHttpRequest已经准备好把一个请求发送到服务器。安全

2服务器

描述一种"发送"状态;此时,已经经过send()方法把一个请求发送到服务器端,可是尚未收到一个响应。并发

3

描述一种"正在接收"状态;此时,已经接收到HTTP响应头部信息,可是消息体部分尚未彻底接收结束。

4

描述一种"已加载"状态;此时,响应已经被彻底接收。


  onreadystatechange事件

   不管readyState值什么时候发生改变,XMLHttpRequest对象都会激发一个readystatechange事件。其 中,onreadystatechange属性接收一个EventListener-向该方法指示不管readyState值什么时候发生改变,该对象都将 激活。

  responseText属性

  这个responseText属性包含客户端接收到的HTTP响应的文本内 容。当readyState值为012时,responseText包含一个空字符串。当readyState值为3(正在接收)时,响应中包含客户 端还未完成的响应信息。当readyState4(已加载)时,该responseText包含完整的响应信息。

  responseXML属性

   此responseXML属性用于当接收到完整的HTTP响应时(readyState4)描述XML响应;此时,Content-Type头部指定 MIME(媒体)类型为text/xmlapplication/xml或以+xml结尾。若是Content-Type头部并不包含这些媒体类型之 一,那么responseXML的值为null。不管什么时候,只要readyState值不为4,那么该responseXML的值也为null

  其实,这个responseXML属性值是一个文档接口类型的对象,用来描述被分析的文档。若是文档不能被分析(例如,若是文档不是良构的或不支持文档相应的字符编码),那么responseXML的值将为null

  status属性

  这个status属性描述了HTTP状态代码,并且其类型为short。并且,仅当readyState值为3(正在接收中)4(已加载)时,这个status属性才可用。当readyState的值小于3时试图存取status的值将引起一个异常。

  statusText属性

  这个statusText属性描述了HTTP状态代码文本;而且仅当readyState值为34才可用。当readyState为其它值时试图存取statusText属性将引起一个异常。

           3、 XMLHttpRequest对象的方法

  XMLHttpRequest对象提供了各类方法用于初始化和处理HTTP请求,下列将逐个展开详细讨论。

  abort()方法

  你可使用这个abort()方法来暂停与一个XMLHttpRequest对象相联系的HTTP请求,从而把该对象复位到未初始化状态。

  open()方法

   你须要调用open(DOMString methodDOMString uriboolean asyncDOMString usernameDOMString password)方法初始化一个XMLHttpRequest对象。其中,method参数是必须提供的-用于指定你想用来发送请求的HTTP方法 (GETPOSTPUTDELETEHEAD)。为了把数据发送到服务器,应该使用POST方法;为了从服务器端检索数据,应该使用GET方法。 另外,uri参数用于指定XMLHttpRequest对象把请求发送到的服务器相应的URI。借助于window.document.baseURI属 性,该uri被解析为一个绝对的URI-换句话说,你可使用相对的URI-它将使用与浏览器解析相对的URI同样的方式被解析。async参数指定是否 请求是异步的-缺省值为true。为了发送一个同步请求,须要把这个参数设置为false。对于要求认证的服务器,你能够提供可选的用户名和口令参数。在 调用open()方法后,XMLHttpRequest对象把它的readyState属性设置为1(打开)而且把responseText responseXMLstatusstatusText属性复位到它们的初始值。另外,它还复位请求头部。注意,若是你调用open()方法而且此 时readyState4,则XMLHttpRequest对象将复位这些值。

  send()方法

  在经过调用 open()方法准备好一个请求以后,你须要把该请求发送到服务器。仅当readyState值为1时,你才能够调用send()方法;不然的 话,XMLHttpRequest对象将引起一个异常。该请求被使用提供给open()方法的参数发送到服务器。当async参数为true 时,send()方法当即返回,从而容许其它客户端脚本处理继续。在调用send()方法后,XMLHttpRequest对象把readyState的 值设置为2(发送)。当服务器响应时,在接收消息体以前,若是存在任何消息体的话,XMLHttpRequest对象将把readyState设置为 3(正在接收中)。当请求完成加载时,它把readyState设置为4(已加载)。对于一个HEAD类型的请求,它将在把readyState值设置为 3后再当即把它设置为4

  send()方法使用一个可选的参数-该参数能够包含可变类型的数据。典型地,你使用它并经过POST方法 把数据发送到服务器。另外,你能够显式地使用null参数调用send()方法,这与不用参数调用它同样。对于大多数其它的数据类型,在调用send() 方法以前,应该使用setRequestHeader()方法(见后面的解释)先设置Content-Type头部。若是在send(data)方法中的 data参数的类型为DOMString,那么,数据将被编码为UTF-8。若是数据是Document类型,那么将使用由 data.xmlEncoding指定的编码串行化该数据。

  setRequestHeader()方法

  该setRequestHeader(DOMString headerDOMString value)方法用来设置请求的头部信息。当readyState值为1时,你能够在调用open()方法后调用这个方法;不然,你将获得一个异常。

  getResponseHeader()方法

  getResponseHeader(DOMString headervalue)方法用于检索响应的头部值。仅当readyState值是34(换句话说,在响应头部可用之后)时,才能够调用这个方法;不然,该方法返回一个空字符串。

  getAllResponseHeaders()方法

  该getAllResponseHeaders()方法以一个字符串形式返回全部的响应头部(每个头部占单独的一行)。若是readyState的值不是34,则该方法返回null

           4、 发送请求

   在AJAX中,许多使用XMLHttpRequest的请求都是从一个HTML事件(例如一个调用JavaScript函数的按钮点击 (onclick)或一个按键(onkeypress))中被初始化的。AJAX支持包括表单校验在内的各类应用程序。有时,在填充表单的其它内容以前要 求校验一个惟一的表单域。例如要求使用一个惟一的UserID来注册表单。若是不是使用AJAX技术来校验这个UserID域,那么整个表单都必须被填充 和提交。若是该UserID不是有效的,这个表单必须被从新提交。例如,一个相应于一个要求必须在服务器端进行校验的Catalog ID的表单域可能按下列形式指定:

form name="validationForm" action="validateForm" method="post"
table
 <tr><tdCatalog Id:/td
  <td
   <input type="text" size="20" id="catalogId" name="catalogId" autocomplete="off" onkeyup="sendRequest()"
  </td
  <td><div id="validationMessage"></div></td
 </tr
/table></form


   前面的HTML使用validationMessage div来显示相应于这个输入域Catalog Id的一个校验消息。onkeyup事件调用一个JavaScript sendRequest()函数。这个sendRequest()函数建立一个XMLHttpRequest对象。建立一个XMLHttpRequest 对象的过程因浏览器实现的不一样而有所区别。若是浏览器支持XMLHttpRequest对象做为一个窗口属性(全部普通的浏览器都是这样的,除了IE 5IE 6以外),那么,代码能够调用XMLHttpRequest的构造器。若是浏览器把XMLHttpRequest对象实现为一个 ActiveXObject对象(就象在IE 5IE 6中同样),那么,代码可使用ActiveXObject的构造器。下面的函数将调用一个init()函数,它负责检查并决定要使用的适当的建立方法- 在建立和返回对象以前。

script type="text/javascript"
function sendRequest(){
 var xmlHttpReq=init();
 function init(){
  if (window.XMLHttpRequest) {
   return new XMLHttpRequest();
  
 else if (window.ActiveXObject) {
  return new ActiveXObject("Microsoft.XMLHTTP");
 }
}
/script


  接下来,你须要使用Open()方法初始化XMLHttpRequest对象-指定HTTP方法和要使用的服务器URL

var catalogId=encodeURIComponent(document.getElementById("catalogId").value);
xmlHttpReq.open("GET"
"validateForm?catalogId=" + catalogId true);


  默认状况下,使用XMLHttpRequest发送的HTTP请求是异步进行的,可是你能够显式地把async参数设置为true,如上面所展现的。
在 这种状况下,对URL validateForm的调用将激活服务器端的一个servlet,可是你应该可以注意到服务器端技术不是根本性的;实际上,该URL多是一个 ASPASP.NETPHP页面或一个Web服务-这可有可无,只要该页面可以返回一个响应-指示CatalogID值是不是有效的-便可。由于你在 做一个异步调用,因此你须要注册一个XMLHttpRequest对象将调用的回调事件处理器-当它的readyState值改变时调用。记 住,readyState值的改变将会激发一个readystatechange事件。你可使用onreadystatechange属性来注册该回调 事件处理器。

xmlHttpReq.onreadystatechange=proce***equest;


  而后,咱们须要使用send()方法发送该请求。由于这个请求使用的是HTTP GET方法,因此,你能够在不指定参数或使用null参数的状况下调用send()方法。

xmlHttpReq.send(null);

           5、 处理请求

  在这个示例中,由于HTTP方法是GET,因此在服务器端的接收servlet将调用一个doGet()方法,该方法将检索在URL中指定的catalogId参数值,而且从一个数据库中检查它的有效性。

   本文示例中的这个servlet须要构造一个发送到客户端的响应;并且,这个示例返回的是XML类型,所以,它把响应的HTTP内容类型设置为 text/xml而且把Cache-Control头部设置为no-cache。设置Cache-Control头部能够阻止浏览器简单地从缓存中重载页 面。

public void doGet(HttpServletRequest request 
HttpServletResponse response)
throws ServletException
IOException {
 ...
 ...
 response.setContentType("text/xml");
 response.setHeader("Cache-Control" "no-cache");
}


  来自于服务器端的响应是一个XML DOM对象,此对象将建立一个XML字符串-其中包含要在客户端进行处理的指令。另外,该XML字符串必须有一个根元素。

out.println("catalogIdvalid/catalogId");


  【注意】XMLHttpRequest对象的设计目的是为了处理由普通文本或XML组成的响应;可是,一个响应也多是另一种类型,若是用户代理(UA)支持这种内容类型的话。

   当请求状态改变时,XMLHttpRequest对象调用使用onreadystatechange注册的事件处理器。所以,在处理该响应以前,你的事 件处理器应该首先检查readyState的值和HTTP状态。当请求完成加载(readyState值为4)而且响应已经完成(HTTP状态 为"OK")时,你就能够调用一个JavaScript函数来处理该响应内容。下列脚本负责在响应完成时检查相应的值并调用一个 proce***esponse()方法。

function proce***equest(){
 if(xmlHttpReq.readyState==4){
  if(xmlHttpReq.status==200){
   proce***esponse();
  }
 }
}


   该proce***esponse()方法使用XMLHttpRequest对象的responseXMLresponseText属性来检索 HTTP响应。如上面所解释的,仅当在响应的媒体类型是text/xmlapplication/xml或以+xml结尾时,这个 responseXML才可用。这个responseText属性将以普通文本形式返回响应。对于一个XML响应,你将按以下方式检索内容:

var msg=xmlHttpReq.responseXML;


  借助于存储在msg变量中的XML,你可使用DOM方法getElementsByTagName()来检索该元素的值:

var catalogId=msg.getElementsByTagName("catalogId")[0].firstChild.nodeValue;


  最后,经过更新Web页面的validationMessage div中的HTML内容并借助于innerHTML属性,你能够测试该元素值以建立一个要显示的消息:

if(catalogId=="valid"){
 var validationMessage = document.getElementById("validationMessage");
 validationMessage.innerHTML = "Catalog Id is Valid";
}
else
{
 var validationMessage = document.getElementById("validationMessage");
 validationMessage.innerHTML = "Catalog Id is not Valid";
}


  6、 小结

   上面就是XMLHttpRequest对象使用的全部细节实现。经过没必要把Web页面寄送到服务器而实现数据传送,XMLHttpRequest对象为 客户端与服务器之间提供了一种动态的交互能力。你可使用JavaScript启动一个请求并处理相应的返回值,而后使用浏览器的DOM方法更新页面中的 数据。

相关文章
相关标签/搜索