firefox下对ajax的onreadystatechange的支持情况分析
firefox下对ajax的onreadystatechange的支持情况分析
发布时间:2016-12-30 来源:查字典编辑
摘要:一、问题:复制代码代码如下:varxmlHttp;functionsavecarttodata(){createXMLHttpRequest...

一、问题:

复制代码 代码如下:

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;

}

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新Javascript教程学习
热门Javascript教程学习
编程开发子分类