firefox下对ajax的onreadystatechange的支持情况分析

一、问题:


代码如下:

var xmlHttp;
function savecarttodata(){
createXMLHttpRequest();
var rndcode = new Date().getTime();
var CartUrl ="a.asp?cache="+rndcode
xmlHttp.onreadystatechange = function(){
.....

}
xmlHttp.open ("GET",CartUrl,true);
xmlHttp.send(null);
}

上面的这段代码, xmlHttp.onreadystatechange = function(){.....};可以在FF下执行,但是如果改成

xmlHttp.open ("GET",Url,false);时就不行了,今天被这个问题整的晕头转向。

原因分析:

其一:这时不能用xmlHttp.send(),需要内容,如果没有内容,要用NULL

其二:经测试后发现,onreadystatechange在IE下都很正常,但在FF3下,只能运行readyState=0时的代码。不能运行readyState=4的代码,在网络上找了一个原因:
在ajax的XMLHttpRequest.onreadystatechange方法的差异:在FF中当状态为1(即XMLHttpRequest已经调用open但还没有调用send时),FF则会继续执行onreadystatechange后面的代码,到执行完后面的代码后,在执行onreadystatechange在状态2,3,4的代码,而IE会等待状态2的到了,执行完onreadystatechange中状态2,3,4的代码后,继续执行后面的代码,这样问题就出现了,经常我们在onreadystatechange的代码要处理从服务器上获得的数据(这个数据只有在onreadystatechange的状态为4时,才可以得到),所以这在IE中不存在问题,因为它会等待onreadystatechange状态4到来以后,在执行onreadystatechange后面的数据,但是由于FF不会等到onreadystatechange状态4到来后在执行onreadystatechange后面的代码,所以后面的代码就不能处理从服务器上获得的数据,那该怎么办呢?

解决方法:使用javascript的闭包(这个解决方法是从GMAP中获得灵感的)。我们传递一个函数给onreadystatechange,在这个函数中处理从服务器上返回的数据,但是onreadystatechange是一个无参函数,那该怎么办呢?方法在我前面的Javascript attachEvent传递参数的办法已经介绍 了,这里再稍微介绍一下,就是传递一个参数给onreadystatechange,但是在onreadystatechange中使用return一个无参函数,在这个无参函数中可以使用这个传入的参数。这个方法在IE和FF中都可以正常运行,所以这不失是一个好方法。

这里提到采用闭包,挺复杂,另外网上有采用了在FF下用onload,也是不管用。经过对错误排除,上面摘要提到的原因,才是根本的,也就是说,在FF下,第一次执行完onreadystatechange后,继续执行到send,但后面就不会再回头执行onreadystatechange,一直傻傻的走下去。

我直接改成:


代码如下:

xmlHttp.onreadystatechange = xmlHandle;
xmlHttp.open ("GET",Url,false);
xmlHttp.send(null);
xmlHttp.onreadystatechange = xmlHandle; //这里加一行挡住FF,让它再搞一次。

function xmlHandle(){
if (xmlHttp.readyState < 4){
......
}else if (xmlHttp.readyState == 4 && xmlHttp.status == 200){
var cartResult = Number(xmlHttp.responseText);
if (cartResult == 1){
window.location.href='a.asp';
}else if (cartResult == 2){
......;
}else{
window.location.href='/';
}
}
}

但是这样也不行,原来ff 3改成:xmlHttp.onreadystatechange = xmlHandle();然而加了括号,IE又不行,唉,原来就觉得FF是鸡皮,现在感觉FF纯属一个打着“支持标准”的称号,却是干着浪费程序员时间的垃圾。但手上这个程序又实在重要,没办法,只有再调试看看有没有更简单的办法,如下:


代码如下:

xmlHttp.open ("GET",Url,false);
xmlHttp.send(null);
if(xmlHttp.status==200)
xmlHandle();

这段代码在IE和FF下可以通用。但由于是同步调用,需要在readyState<4时未取得结果前出现提示,这对于网速慢的客户很友好。然而要在本机获得这种等待反应时的情况,由于本机反应快,会造成看不到给客户提示,因此暂时先不用这个代码

只有加入浏览器类型分析。


代码如下:

function getOs()
{
var OsObject = "";
if(navigator.userAgent.indexOf("MSIE")>0) {
return "MSIE"; //IE浏览器
}
if(isFirefox=navigator.userAgent.indexOf("Firefox")>0){
return "Firefox"; //Firefox浏览器
}
if(isSafari=navigator.userAgent.indexOf("Safari")>0) {
return "Safari"; //Safan浏览器
}
if(isCamino=navigator.userAgent.indexOf("Camino")>0){
return "Camino"; //Camino浏览器
}
if(isMozilla=navigator.userAgent.indexOf("Gecko/")>0){
return "Gecko"; //Gecko浏览器
}
}

然后把AJAX代码改为:


代码如下:

var rndcode = new Date().getTime();
var CartUrl ="a.asp?cache="+rndcode
var btype=getOs();
xmlHttp.onreadystatechange = (btype!="Firefox")?xmlHandle():xmlHandle;
xmlHttp.open ("GET",CartUrl,false);
xmlHttp.send(null);
xmlHttp.onreadystatechange = (btype!="Firefox")?xmlHandle():xmlHandle;

例二


代码如下:

//获取游览器的类型,为解决onreadystatechange不兼容的问题
function getOs()
{
var OsObject = "";
if(navigator.userAgent.indexOf("MSIE")>0) {
return "MSIE"; //IE浏览器
}
if(isFirefox=navigator.userAgent.indexOf("Firefox")>0){
return "Firefox"; //Firefox浏览器
}
if(isSafari=navigator.userAgent.indexOf("Safari")>0) {
return "Safari"; //Safan浏览器
}
if(isCamino=navigator.userAgent.indexOf("Camino")>0){
return "Camino"; //Camino浏览器
}
if(isMozilla=navigator.userAgent.indexOf("Gecko/")>0){
return "Gecko"; //Gecko浏览器
}
}
var objHttp;
function searchCommodityByGroupId(groupId)
{
objHttp = getHttpRequest();
var tt=new Date();
var url="getCommodityListByGroupId.htm?commodityGroupId="+groupId+"&time="+tt;
var btype=getOs();

objHttp.onreadystatechange=(btype=="Firefox")?getCommodity():getCommodity;
objHttp.open("GET",url,false);
objHttp.send(null);
objHttp.onreadystatechange=(btype=="Firefox")?getCommodity():getCommodity;
}
function getCommodity(){

if(objHttp.readyState==4)
{
if(objHttp.status==200)
{
document.getElementById("commodityDiv").innerHTML=objHttp.responseText;
}
}
}

function getHttpRequest(){
var httpRequest;
if (window.XMLHttpRequest){
httpRequest = new XMLHttpRequest();
if (httpRequest.overrideMimeType){
httpRequest.overrideMimeType('text/xml');
}
}else if (window.ActiveXObject){
try{
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
}catch(e){
try {
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){}
}
}
return httpRequest;
}

(0)

相关推荐

  • AJax 学习笔记二(onreadystatechange的作用)

    当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了onreadyStateChange事件实现这一功能.这类似于回调函数的做法.onreadyStateChange事件可指定一个事件处理函数来处理XMLHttpRequest对象的执行结果,如: 复制代码 代码如下: ajaxObj=createAjaxObject(); var url="/MyTodoes/FetchText?id="+id; ajaxOb

  • Ajax xmlHttpRequest的status的值的含义

    xmlHttpRequest对象的status代表当前http请求的状态,是一个长整型数据,现在介绍一下它的含义. http请求状态及其含义表 1xx - 信息提示 100 - 初始的请求已经接受,客户应当继续发送请求的其余部分.(HTTP 1.1新) 101 - 服务器将遵从客户的请求转换到另外一种协议.(HTTP 1.1新) 2xx - 成功 200 - OK 一切正常,对GET和POST请求的应答文档跟在后面. 201 - Created 服务器已经创建了文档,Location头给出了它的

  • ajax+php打造进度条代码[readyState各状态说明]

    readyState == 状态(0,1,2,3,4) 0:请求未初始化,还没调用open 1:请求已经建立,但还没有发送,还没调用send 2:请求已发送,并且正在处理 3:请求正在处理,通常响应中已有部分数据可调用 4:完毕 复制代码 代码如下: var xmlHttp; function create() if(window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");//IE浏览器 } el

  • ajax+php打造进度条 readyState各状态

    用Ajax+php打造进度条,其实很简单. readyState == 状态(0,1,2,3,4) 0:请求未初始化,还没调用open 1:请求已经建立,但还没有发送,还没调用send 2:请求已发送,并且正在处理 3:请求正在处理,通常响应中已有部分数据可调用 4:完毕 复制代码 代码如下: var xmlHttp; function create() if(window.ActiveXObject) { xmlHttp = new ActiveXObject("Microsoft.XMLHT

  • Ajax 给 XMLHttpReq.onreadystatechange传递参数

    Ajax 给 XMLHttpReq.onreadystatechange传递参数 通过: xmlhttp.onreadystatechange= function(){xx(123)}; or xmlhttp.onreadystatechange= new Function("xx(123)"); 就可以了. 复制代码 代码如下: Ajax 给 XMLHttpReq.onreadystatechange传递参数 通过: xmlhttp.onreadystatechange= funct

  • AJAX(XMLHttpRequest.status)状态码

    下面是Jquery中AJAX参数详细列表: 参数名 类型 描述 url String (默认: 当前页地址) 发送请求的地址. type String (默认: "GET") 请求方式 ("POST" 或 "GET"), 默认为 "GET".注意:其它 HTTP 请求方法,如 PUT 和 DELETE 也可以使用,但仅部分浏览器支持. timeout Number 设置请求超时时间(毫秒).此设置将覆盖全局设置. async

  • 探讨Ajax中有关readyState(状态值)和status(状态码)的问题

    先看下面一段代码,然后给大家详细介绍,Ajax中有关readyState(状态值)和status(状态码)的问题,具体内容如下所示: var getXmlHttpRequest = function () { try{ //主流浏览器提供了XMLHttpRequest对象 return new XMLHttpRequest(); }catch(e){ //低版本的IE浏览器没有提供XMLHttpRequest对象,IE6以下 //所以必须使用IE浏览器的特定实现ActiveXObject ret

  • javascript学习笔记(七)Ajax和Http状态码

    Ajax及其工作原理 AJAX 是一种与服务器交换数据无需刷新网页的技术,最早由Google公司在谷歌地图里使用,并迅速风靡. AJAX是不能跨域的,如需跨域,可以使用document.domain='a.com':或者使用服务器代理,代理XMLHttpRequest文件 AJAX是基于现有的Internet标准,并且联合使用它们: XMLHttpRequest 对象 (异步的与服务器交换数据) JavaScript/DOM (信息显示/交互) CSS (给数据定义样式) XML (作为转换数据

  • ajax readyState的五种状态详解

    在<Pragmatic Ajax A Web 2.0 Primer >中对readyStae状态的介绍,摘译如下: 0: (Uninitialized) the send( ) method has not yet been invoked. 1: (Loading) the send( ) method has been invoked, request in progress. 2: (Loaded) the send( ) method has completed, entire res

  • firefox下对ajax的onreadystatechange的支持情况分析

    一.问题: 复制代码 代码如下: var xmlHttp; function savecarttodata(){ createXMLHttpRequest(); var rndcode = new Date().getTime(); var CartUrl ="a.asp?cache="+rndcode xmlHttp.onreadystatechange = function(){ ..... } xmlHttp.open ("GET",CartUrl,true)

  • firefox下jquery ajax返回object XMLDocument处理方法

    在firefox下使用jquery ajax处理struts2 返回json类型的时候,ajax执行成功返回结果为 [object XMLDocument]. 处理办法:在getWriter.print():前面加上一行代码 复制代码 代码如下: ServletActionContext.getResponse().setContentType("text/html;charset=UTF-8");

  • Boa服务器下的ajax与cgi通信

    最近在最有做一个嵌入式课程设计,要求是利用基于cortax a8的物联网实验箱做一个简单的嵌入式网页交互系统作为课程设计来验收评分.因为本身自己是学前端的,所以网页部分并不是重点,主要是和boa服务器之间的通信,课程实验给的例子是直接使用printf来打印html标签形成新的页面,有过前端开发经验的人都知道这种做法效率低下而且没有办法实现异步刷新,所以博主采用ajax来进行boa服务器下的异步通信. 主要实现及踩过的坑如下: 1. get 还是 post请求:怎么发请求参见W3School上的a

  • Jquery在IE7下无法使用 $.ajax解决方法

    通过查看源码发现 复制代码 代码如下: // Create the request object; Microsoft failed to properly // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available // This function can be overriden by calling jQuery.ajaxSetup xhr:function(){ retu

  • 关于IE浏览器以及Firefox下的javascript冒泡事件的响应层级

    假设在我们页面有这么一段标签: 复制代码 代码如下: <body> <div id="testDiv" style="width:200px;height:200px;background:#c0c0c0;"></div> </body> 现在在页面加入这么一段脚本: 复制代码 代码如下: <script type="text/javascript"> window.onload=fun

  • 页面向下滚动ajax获取数据的实现方法(兼容手机)

    页面向下滚动ajax获取数据的实现方法(兼容手机) $(window).scroll(function () { var scrollTop = $(this).scrollTop(); var scrollHeight = $(document).height(); var windowHeight = $(this).height(); if (scrollTop + windowHeight >= scrollHeight) { loadPromotions(); } }); var pa

  • .NET2.0环境下的Ajax选型和应用(提供Demo源码下载)

    主题:.NET2.0环境下的Ajax选型和应用 研究需要解决的问题: 1 Ajax 应用框架的选型及其性能对比 2 如何应用 Ajax 3 应用 Ajax 过程中应该着重注意的问题 研究者: Jimmy.Ke 时间: 2006-11-13 一 Demo说明 Ajax Demo Web Site 是一个完整的 .NET Website ,其中包含 5 个 ASPX 页面及其对应的 CS 文件. 为了方便对比, Demo 中使用了三种 Ajax 应用方式: 一是使用微软提供的 Atlas 应用框架,

  • 使用jQuery解决IE与FireFox下createElement方法的差异

    当我们需要动态生成DOM对象的时候,会使用createElement的方法创建.但是在IE和Firefox下,createElement方法是有差异的. 在 IE 中,可以使用以下两种方式来创建一个元素: 1.document.createElement('table') 2.document.createElement('<table border="0">') 而在 Firefox 只支持: document.createElement('table') 同时,如果添加

  • textContent在Firefox下与innerText等效的属性

    在IE和Opear下,DOM对象支持innerText属性,可以很方便的去除HTML标签. 但在Firefox不支持该属性,好在FF下的DOM对象支持textContent,该属性与innerText等效. 演示实例: <p id="TestObj">Hi,I'm <strong>cnlei</strong>.Welcome to my homepage:<a href="http://www.cnlei.com">h

  • IE和Firefox下javascript的兼容写法小结

    1.发现IE下input标签的id属性默认和name属性相同,而Firefox必须明确写出id属性的名称否则不能使用id属性. 如:<input type="text" name="username" value=""> 在IE下如下代码可以执行而在Firefox下却不可以: <script> alert(document.getElementById("username").value); </

随机推荐