AJAX的教程都讲述了如何使用异步的方式来请求一项服务,通过异步请求来增强客户体验。但在某些情况下,也许采用同步的请求更好,就像电影那样,魔鬼并不都是坏人。
我们依然从得到XMLHttpRequest对象开始:
var xmlHttp;
function createXMLHttpRequest() {
if (window.ActiveXObject) {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} else if (window.XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}
}
createXMLHttpRequest();
function doRequest() {
// TODO
}
function handleStateChange() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
alert(xmlHttp.responseText);
}
}
}
然后创建一个<input />按钮(为何?在异步和同步的情况下可以看清楚按钮的状态),让它执行doRequest()函数。那么现在让我们完成doRequest()函数:
function doRequest() {
if(xmlHttp) {
xmlHttp.open("GET", "request.jsp", false);
xmlHttp.onReadyStateChange = handleStateChange;
xmlHttp.send(null);
}
}
魔术就产生在xmlHttp.open()函数的第三个参数。当该参数设置为true时,就是异步的请求,否则为同步的请求。某些介绍AJAX的书上省略了第三个参数,而直接写成 xmlHttp.open("GET", "request.jsp"),那是因为该函数是默认采用异步的方式。函数open(method, url, async, user, password)可具体查看相应的文档(http://www.w3.org/TR/XMLHttpRequest)。
XMLHttpRequest 对象的 open() 方法来完成。该方法有五个参数:
·request-type:发送请求的类型。典型的值是 GET 或 POST,但也可以发送 HEAD 请求。
·url:要连接的 URL。
·asynch:如果希望使用异步连接则为 true,否则为 false。该参数是可选的,默认为 true。
·username:如果需要身份验证,则可以在此指定用户名。该可选参数没有
·password:如果需要身份验证,则可以在此指定口令。该可选参数没有默认值。
request.jsp则很简单,不再介绍,如下:
// 清除掉缓存,否则窗子上的污迹会迷惑你的眼睛
response.setHeader("pragma","no-cache");
response.setHeader("cache-control","no-cache");
response.setDateHeader("expires", 0);
// 我们使当前的线程停止5秒钟,来模拟耗时的操作
Thread.currentThread().sleep(5000);
out.println("Hello, " + new java.util.Date());
好啦,让我们来运行一下吧。点击那个按钮,看看发生了什么?我们发现按钮按下去了没有弹起来,而且我们也不能进行其它的操作。5秒钟后,弹出了请求的结果。
把 xmlHttp.open() 的第三个参数改为"true"呢?自己试吧。
奇怪的是Opera开始无法执行,后来又莫明其妙的好了。但是按钮没有那种按下去不弹起来的效果。若多次点击会多次执行。而Firefox不能运行,也不报错。经过大量的测试后发现firefox在同步的情况下无法正常调用onreadystatechange设定的函数。那么把open的第三个参数改成true吧!或者用下面的方法来实现:
function doRequest() {
if(xmlHttp) {
xmlHttp.open("GET", "request.jsp", false);
// xmlHttp.onreadystatechange = handleStateChange;
xmlHttp.send(null);
alert(xmlHttp.responseText);
}
}
即直接在doRequest()函数后调用业务逻辑,而不能采用回调的方式。
记录一下运行环境,以便以后进一步测试用:IE 7, Opera 9.10, Mozilla Firefox 2.0.0.1