@H_404_223@四、 发送请求@H_404_223@ @H_404_223@ 在AJAX@H_404_223@中,许多使用XMLHttpRequest@H_404_223@的请求都是从一个HTML@H_404_223@事件(例如一个调用JavaScript@H_404_223@函数的按钮点击 (onclick)@H_404_223@或一个按键(onkeypress)@H_404_223@)中被初始化的。AJAX@H_404_223@支持包括表单校验在内的各种应用程序。有时,在填充表单的其它内容之前要 求校验一个唯一的表单域。例如要求使用一个唯一的UserID@H_404_223@来注册表单。如果不是使用AJAX@H_404_223@技术来校验这个UserID@H_404_223@域,那么整个表单都必须被填充 和提交。如果该UserID@H_404_223@不是有效的,这个表单必须被重新提交。例如,一个相应于一个要求必须在服务器端进行校验的Catalog ID@H_404_223@的表单域可能按下列形式指定:@H_404_223@
<form name="validationForm" action="validateForm" method="post"@H_404_223@> @H_404_223@<table@H_404_223@> @H_404_223@ <tr@H_404_223@><td@H_404_223@>Catalog Id:@H_404_223@</td@H_404_223@> @H_404_223@ <td@H_404_223@> @H_404_223@ <input type="text" size="20" id="catalogId" name="catalogId" autocomplete="off" onkeyup="sendRequest()"@H_404_223@> @H_404_223@ </td@H_404_223@> @H_404_223@ <td@H_404_223@><div id="validationMessage"@H_404_223@></div@H_404_223@></td@H_404_223@> @H_404_223@ </tr@H_404_223@> @H_404_223@</table@H_404_223@></form@H_404_223@>@H_404_223@ |
@H_404_223@ 前面的HTML@H_404_223@使用validationMessage div@H_404_223@来显示相应于这个输入域Catalog Id@H_404_223@的一个校验消息。onkeyup@H_404_223@事件调用一个JavaScript sendRequest()@H_404_223@函数。这个sendRequest()@H_404_223@函数创建一个XMLHttpRequest@H_404_223@对象。创建一个XMLHttpRequest @H_404_223@对象的过程因浏览器实现的不同而有所区别。如果浏览器支持XMLHttpRequest@H_404_223@对象作为一个窗口属性(@H_404_223@所有普通的浏览器都是这样的,除了IE 5@H_404_223@和IE 6@H_404_223@之外)@H_404_223@,那么,代码可以调用XMLHttpRequest@H_404_223@的构造器。如果浏览器把XMLHttpRequest@H_404_223@对象实现为一个 ActiveXObject@H_404_223@对象(@H_404_223@就象在IE 5@H_404_223@和IE 6@H_404_223@中一样)@H_404_223@,那么,代码可以使用ActiveXObject@H_404_223@的构造器。下面的函数将调用一个init()@H_404_223@函数,它负责检查并决定要使用的适当的创建方法- @H_404_223@在创建和返回对象之前。@H_404_223@
<script type="text/javascript"@H_404_223@> function sendRequest(){ @H_404_223@ var xmlHttpReq=init(); @H_404_223@ function init(){ @H_404_223@ if (window.XMLHttpRequest) { @H_404_223@ return new XMLHttpRequest(); @H_404_223@ } @H_404_223@ else if (window.ActiveXObject) { @H_404_223@ return new ActiveXObject("Microsoft.XMLHTTP"); @H_404_223@ } } @H_404_223@</script@H_404_223@>@H_404_223@ |
@H_404_223@ 接下来,你需要使用Open()@H_404_223@方法初始化XMLHttpRequest@H_404_223@对象-@H_404_223@指定HTTP@H_404_223@方法和要使用的服务器URL@H_404_223@。@H_404_223@
var catalogId=encodeURIComponent(document.getElementById("catalogId").value); xmlHttpReq.open("GET"@H_404_223@, "validateForm?catalogId=" + catalogId@H_404_223@, true);@H_404_223@@H_404_223@ |
@H_404_223@ 默认情况下,使用XMLHttpRequest@H_404_223@发送的HTTP@H_404_223@请求是异步进行的,但是你可以显式地把async@H_404_223@参数设置为true@H_404_223@,如上面所展示的。 @H_404_223@在 这种情况下,对URL validateForm@H_404_223@的调用将激活服务器端的一个servlet@H_404_223@,但是你应该能够注意到服务器端技术不是根本性的;实际上,该URL@H_404_223@可能是一个 ASP@H_404_223@,ASP.NET@H_404_223@或PHP@H_404_223@页面或一个Web@H_404_223@服务-@H_404_223@这无关紧要,只要该页面能够返回一个响应-@H_404_223@指示CatalogID@H_404_223@值是否是有效的-@H_404_223@即可。因为你在 作一个异步调用,所以你需要注册一个XMLHttpRequest@H_404_223@对象将调用的回调事件处理器-@H_404_223@当它的readyState@H_404_223@值改变时调用。记 住,readyState@H_404_223@值的改变将会激发一个readystatechange@H_404_223@事件。你可以使用onreadystatechange@H_404_223@属性来注册该回调 事件处理器。@H_404_223@
xmlHttpReq.onreadystatechange=processRequest;@H_404_223@ |
@H_404_223@ 然后,我们需要使用send()@H_404_223@方法发送该请求。因为这个请求使用的是HTTP GET@H_404_223@方法,所以,你可以在不指定参数或使用null@H_404_223@参数的情况下调用send()@H_404_223@方法。@H_404_223@
xmlHttpReq.send(null);@H_404_223@ |
@H_404_223@五、 处理请求@H_404_223@ @H_404_223@ 在这个示例中,因为HTTP@H_404_223@方法是GET@H_404_223@,所以在服务器端的接收servlet@H_404_223@将调用一个doGet()@H_404_223@方法,该方法将检索在URL@H_404_223@中指定的catalogId@H_404_223@参数值,并且从一个数据库中检查它的有效性。 @H_404_223@ 本文示例中的这个servlet@H_404_223@需要构造一个发送到客户端的响应;而且,这个示例返回的是XML@H_404_223@类型,因此,它把响应的HTTP@H_404_223@内容类型设置为 text/xml@H_404_223@并且把Cache-Control@H_404_223@头部设置为no-cache@H_404_223@。设置Cache-Control@H_404_223@头部可以阻止浏览器简单地从缓存中重载页 面。@H_404_223@
public void doGet(HttpServletRequest request@H_404_223@, HttpServletResponse response) throws ServletException@H_404_223@, IOException { @H_404_223@ ... @H_404_223@ ... @H_404_223@ response.setContentType("text/xml"); @H_404_223@ response.setHeader("Cache-Control"@H_404_223@, "no-cache"); }@H_404_223@@H_404_223@ |
@H_404_223@ 来自于服务器端的响应是一个XML DOM@H_404_223@对象,此对象将创建一个XML@H_404_223@字符串-@H_404_223@其中包含要在客户端进行处理的指令。另外,该XML@H_404_223@字符串必须有一个根元素。@H_404_223@
out.println("@H_404_223@<catalogId@H_404_223@>valid@H_404_223@</catalogId@H_404_223@>");@H_404_223@@H_404_223@ |
@H_404_223@ 【注意】XMLHttpRequest@H_404_223@对象的设计目的是为了处理由普通文本或XML@H_404_223@组成的响应;但是,一个响应也可能是另外一种类型,如果用户代理(UA)@H_404_223@支持这种内容类型的话。 @H_404_223@ 当请求状态改变时,XMLHttpRequest@H_404_223@对象调用使用onreadystatechange@H_404_223@注册的事件处理器。因此,在处理该响应之前,你的事 件处理器应该首先检查readyState@H_404_223@的值和HTTP@H_404_223@状态。当请求完成加载(readyState@H_404_223@值为4@H_404_223@)并且响应已经完成(HTTP@H_404_223@状态 为"OK"@H_404_223@)时,你就可以调用一个JavaScript@H_404_223@函数来处理该响应内容。下列脚本负责在响应完成时检查相应的值并调用一个 processResponse()@H_404_223@方法。@H_404_223@
function processRequest(){ @H_404_223@ if(xmlHttpReq.readyState==4){ @H_404_223@ if(xmlHttpReq.status==200){ @H_404_223@ processResponse(); @H_404_223@ } @H_404_223@ } }@H_404_223@@H_404_223@ |
@H_404_223@ 该processResponse()@H_404_223@方法使用XMLHttpRequest@H_404_223@对象的responseXML@H_404_223@和responseText@H_404_223@属性来检索 HTTP@H_404_223@响应。如上面所解释的,仅当在响应的媒体类型是text/xml@H_404_223@,application/xml@H_404_223@或以+xml@H_404_223@结尾时,这个 responseXML@H_404_223@才可用。这个responseText@H_404_223@属性将以普通文本形式返回响应。对于一个XML@H_404_223@响应,你将按如下方式检索内容:@H_404_223@
var msg=xmlHttpReq.responseXML;@H_404_223@ |
@H_404_223@ 借助于存储在msg@H_404_223@变量中的XML@H_404_223@,你可以使用DOM@H_404_223@方法getElementsByTagName()@H_404_223@来检索该元素的值:@H_404_223@
var catalogId=msg.getElementsByTagName("catalogId")[0].firstChild.nodeValue;@H_404_223@ |
@H_404_223@ 最后,通过更新Web@H_404_223@页面的validationMessage div@H_404_223@中的HTML@H_404_223@内容并借助于innerHTML@H_404_223@属性,你可以测试该元素值以创建一个要显示的消息:@H_404_223@
if(catalogId=="valid"){ @H_404_223@ var validationMessage = document.getElementById("validationMessage"); @H_404_223@ validationMessage.innerHTML = "Catalog Id is Valid"; } else { @H_404_223@ var validationMessage = document.getElementById("validationMessage"); @H_404_223@ validationMessage.innerHTML = "Catalog Id is not Valid"; }@H_404_223@@H_404_223@ |
@H_404_223@ @H_404_223@六、 小结@H_404_223@ @H_404_223@ 上面就是XMLHttpRequest@H_404_223@对象使用的所有细节实现。通过不必把Web@H_404_223@页面寄送到服务器而实现数据传送,XMLHttpRequest@H_404_223@对象为 客户端与服务器之间提供了一种动态的交互能力。你可以使用JavaScript@H_404_223@启动一个请求并处理相应的返回值,然后使用浏览器的DOM@H_404_223@方法更新页面中的 数据。@H_404_223@ |