博客首页 注册 建议与交流 排行榜 加入友情链接
推荐 投诉 搜索: 帮助

linxh

linxh.cublog.cn
XMLHttpRequest的同步请求和Firefox的问题
 
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

 原文地址 http://hi.baidu.com/lieyu063/blog/item/560ffceaf53276d2d439c9dc.html
发表于: 2007-07-14,修改于: 2007-07-14 20:11,已浏览1129次,有评论1条 推荐 投诉
网友: ylhyh 时间:2008-06-20 10:04:31 IP地址:59.40.119.★
不错


给我留言
版权所有 ChinaUnix.net 页面生成时间:2.62484