4、 发送请求 在AJAX中,许多使用XMLHttpRequest的请求都是从一个HTML事件(例如一个调用JavaScript函数的按钮点击 (onclick)或一个按键(onkeypress))中被初始化的。AJAX支持包括表单校验在内的各类应用程序。有时,在填充表单的其它内容以前要 求校验一个惟一的表单域。例如要求使用一个惟一的UserID来注册表单。若是不是使用AJAX技术来校验这个UserID域,那么整个表单都必须被填充 和提交。若是该UserID不是有效的,这个表单必须被从新提交。例如,一个相应于一个要求必须在服务器端进行校验的Catalog ID的表单域可能按下列形式指定:
<form name="validationForm" action="validateForm" method="post"> <table> <tr><td>Catalog 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 5和IE 6以外),那么,代码能够调用XMLHttpRequest的构造器。若是浏览器把XMLHttpRequest对象实现为一个 ActiveXObject对象(就象在IE 5和IE 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多是一个 ASP,ASP.NET或PHP页面或一个Web服务-这可有可无,只要该页面可以返回一个响应-指示CatalogID值是不是有效的-便可。由于你在 做一个异步调用,因此你须要注册一个XMLHttpRequest对象将调用的回调事件处理器-当它的readyState值改变时调用。记 住,readyState值的改变将会激发一个readystatechange事件。你可使用onreadystatechange属性来注册该回调 事件处理器。
xmlHttpReq.onreadystatechange=proce***equest; |
而后,咱们须要使用send()方法发送该请求。由于这个请求使用的是HTTP GET方法,因此,你能够在不指定参数或使用null参数的状况下调用send()方法。
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("<catalogId>valid</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对象的responseXML和responseText属性来检索 HTTP响应。如上面所解释的,仅当在响应的媒体类型是text/xml,application/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方法更新页面中的 数据。 |