firefox下對(duì)ajax的onreadystatechange的支持情況分析
更新時(shí)間:2009年12月14日 23:25:36 作者:
firefox下對(duì)ajax的onreadystatechange的支持分析。用的到的朋友可以參考下。
一、問(wèn)題:
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下執(zhí)行,但是如果改成
xmlHttp.open ("GET",Url,false);時(shí)就不行了,今天被這個(gè)問(wèn)題整的暈頭轉(zhuǎn)向。
原因分析:
其一:這時(shí)不能用xmlHttp.send(),需要內(nèi)容,如果沒(méi)有內(nèi)容,要用NULL
其二:經(jīng)測(cè)試后發(fā)現(xiàn),onreadystatechange在IE下都很正常,但在FF3下,只能運(yùn)行readyState=0時(shí)的代碼。不能運(yùn)行readyState=4的代碼,在網(wǎng)絡(luò)上找了一個(gè)原因:
在ajax的XMLHttpRequest.onreadystatechange方法的差異:在FF中當(dāng)狀態(tài)為1(即XMLHttpRequest已經(jīng)調(diào)用open但還沒(méi)有調(diào)用send時(shí)),F(xiàn)F則會(huì)繼續(xù)執(zhí)行onreadystatechange后面的代碼,到執(zhí)行完后面的代碼后,在執(zhí)行onreadystatechange在狀態(tài)2,3,4的代碼,而IE會(huì)等待狀態(tài)2的到了,執(zhí)行完onreadystatechange中狀態(tài)2,3,4的代碼后,繼續(xù)執(zhí)行后面的代碼,這樣問(wèn)題就出現(xiàn)了,經(jīng)常我們?cè)趏nreadystatechange的代碼要處理從服務(wù)器上獲得的數(shù)據(jù)(這個(gè)數(shù)據(jù)只有在onreadystatechange的狀態(tài)為4時(shí),才可以得到),所以這在IE中不存在問(wèn)題,因?yàn)樗鼤?huì)等待onreadystatechange狀態(tài)4到來(lái)以后,在執(zhí)行onreadystatechange后面的數(shù)據(jù),但是由于FF不會(huì)等到onreadystatechange狀態(tài)4到來(lái)后在執(zhí)行onreadystatechange后面的代碼,所以后面的代碼就不能處理從服務(wù)器上獲得的數(shù)據(jù),那該怎么辦呢?
解決方法:使用javascript的閉包(這個(gè)解決方法是從GMAP中獲得靈感的)。我們傳遞一個(gè)函數(shù)給onreadystatechange,在這個(gè)函數(shù)中處理從服務(wù)器上返回的數(shù)據(jù),但是onreadystatechange是一個(gè)無(wú)參函數(shù),那該怎么辦呢?方法在我前面的Javascript attachEvent傳遞參數(shù)的辦法已經(jīng)介紹 了,這里再稍微介紹一下,就是傳遞一個(gè)參數(shù)給onreadystatechange,但是在onreadystatechange中使用return一個(gè)無(wú)參函數(shù),在這個(gè)無(wú)參函數(shù)中可以使用這個(gè)傳入的參數(shù)。這個(gè)方法在IE和FF中都可以正常運(yùn)行,所以這不失是一個(gè)好方法。
這里提到采用閉包,挺復(fù)雜,另外網(wǎng)上有采用了在FF下用onload,也是不管用。經(jīng)過(guò)對(duì)錯(cuò)誤排除,上面摘要提到的原因,才是根本的,也就是說(shuō),在FF下,第一次執(zhí)行完onreadystatechange后,繼續(xù)執(zhí)行到send,但后面就不會(huì)再回頭執(zhí)行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='/';
}
}
}
但是這樣也不行,原來(lái)ff 3改成:xmlHttp.onreadystatechange = xmlHandle();然而加了括號(hào),IE又不行,唉,原來(lái)就覺(jué)得FF是雞皮,現(xiàn)在感覺(jué)FF純屬一個(gè)打著“支持標(biāo)準(zhǔn)”的稱號(hào),卻是干著浪費(fèi)程序員時(shí)間的垃圾。但手上這個(gè)程序又實(shí)在重要,沒(méi)辦法,只有再調(diào)試看看有沒(méi)有更簡(jiǎn)單的辦法,如下:
xmlHttp.open ("GET",Url,false);
xmlHttp.send(null);
if(xmlHttp.status==200)
xmlHandle();
這段代碼在IE和FF下可以通用。但由于是同步調(diào)用,需要在readyState<4時(shí)未取得結(jié)果前出現(xiàn)提示,這對(duì)于網(wǎng)速慢的客戶很友好。然而要在本機(jī)獲得這種等待反應(yīng)時(shí)的情況,由于本機(jī)反應(yīng)快,會(huì)造成看不到給客戶提示,因此暫時(shí)先不用這個(gè)代碼
只有加入瀏覽器類型分析。
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不兼容的問(wèn)題
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;
}
復(fù)制代碼 代碼如下:
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下執(zhí)行,但是如果改成
xmlHttp.open ("GET",Url,false);時(shí)就不行了,今天被這個(gè)問(wèn)題整的暈頭轉(zhuǎn)向。
原因分析:
其一:這時(shí)不能用xmlHttp.send(),需要內(nèi)容,如果沒(méi)有內(nèi)容,要用NULL
其二:經(jīng)測(cè)試后發(fā)現(xiàn),onreadystatechange在IE下都很正常,但在FF3下,只能運(yùn)行readyState=0時(shí)的代碼。不能運(yùn)行readyState=4的代碼,在網(wǎng)絡(luò)上找了一個(gè)原因:
在ajax的XMLHttpRequest.onreadystatechange方法的差異:在FF中當(dāng)狀態(tài)為1(即XMLHttpRequest已經(jīng)調(diào)用open但還沒(méi)有調(diào)用send時(shí)),F(xiàn)F則會(huì)繼續(xù)執(zhí)行onreadystatechange后面的代碼,到執(zhí)行完后面的代碼后,在執(zhí)行onreadystatechange在狀態(tài)2,3,4的代碼,而IE會(huì)等待狀態(tài)2的到了,執(zhí)行完onreadystatechange中狀態(tài)2,3,4的代碼后,繼續(xù)執(zhí)行后面的代碼,這樣問(wèn)題就出現(xiàn)了,經(jīng)常我們?cè)趏nreadystatechange的代碼要處理從服務(wù)器上獲得的數(shù)據(jù)(這個(gè)數(shù)據(jù)只有在onreadystatechange的狀態(tài)為4時(shí),才可以得到),所以這在IE中不存在問(wèn)題,因?yàn)樗鼤?huì)等待onreadystatechange狀態(tài)4到來(lái)以后,在執(zhí)行onreadystatechange后面的數(shù)據(jù),但是由于FF不會(huì)等到onreadystatechange狀態(tài)4到來(lái)后在執(zhí)行onreadystatechange后面的代碼,所以后面的代碼就不能處理從服務(wù)器上獲得的數(shù)據(jù),那該怎么辦呢?
解決方法:使用javascript的閉包(這個(gè)解決方法是從GMAP中獲得靈感的)。我們傳遞一個(gè)函數(shù)給onreadystatechange,在這個(gè)函數(shù)中處理從服務(wù)器上返回的數(shù)據(jù),但是onreadystatechange是一個(gè)無(wú)參函數(shù),那該怎么辦呢?方法在我前面的Javascript attachEvent傳遞參數(shù)的辦法已經(jīng)介紹 了,這里再稍微介紹一下,就是傳遞一個(gè)參數(shù)給onreadystatechange,但是在onreadystatechange中使用return一個(gè)無(wú)參函數(shù),在這個(gè)無(wú)參函數(shù)中可以使用這個(gè)傳入的參數(shù)。這個(gè)方法在IE和FF中都可以正常運(yùn)行,所以這不失是一個(gè)好方法。
這里提到采用閉包,挺復(fù)雜,另外網(wǎng)上有采用了在FF下用onload,也是不管用。經(jīng)過(guò)對(duì)錯(cuò)誤排除,上面摘要提到的原因,才是根本的,也就是說(shuō),在FF下,第一次執(zhí)行完onreadystatechange后,繼續(xù)執(zhí)行到send,但后面就不會(huì)再回頭執(zhí)行onreadystatechange,一直傻傻的走下去。
我直接改成:
復(fù)制代碼 代碼如下:
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='/';
}
}
}
但是這樣也不行,原來(lái)ff 3改成:xmlHttp.onreadystatechange = xmlHandle();然而加了括號(hào),IE又不行,唉,原來(lái)就覺(jué)得FF是雞皮,現(xiàn)在感覺(jué)FF純屬一個(gè)打著“支持標(biāo)準(zhǔn)”的稱號(hào),卻是干著浪費(fèi)程序員時(shí)間的垃圾。但手上這個(gè)程序又實(shí)在重要,沒(méi)辦法,只有再調(diào)試看看有沒(méi)有更簡(jiǎn)單的辦法,如下:
復(fù)制代碼 代碼如下:
xmlHttp.open ("GET",Url,false);
xmlHttp.send(null);
if(xmlHttp.status==200)
xmlHandle();
這段代碼在IE和FF下可以通用。但由于是同步調(diào)用,需要在readyState<4時(shí)未取得結(jié)果前出現(xiàn)提示,這對(duì)于網(wǎng)速慢的客戶很友好。然而要在本機(jī)獲得這種等待反應(yīng)時(shí)的情況,由于本機(jī)反應(yīng)快,會(huì)造成看不到給客戶提示,因此暫時(shí)先不用這個(gè)代碼
只有加入瀏覽器類型分析。
復(fù)制代碼 代碼如下:
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代碼改為:
復(fù)制代碼 代碼如下:
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;
例二
復(fù)制代碼 代碼如下:
//獲取游覽器的類型,為解決onreadystatechange不兼容的問(wèn)題
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;
}
您可能感興趣的文章:
- ajax readyState的五種狀態(tài)詳解
- Ajax xmlHttpRequest的status的值的含義
- ajax+php打造進(jìn)度條 readyState各狀態(tài)
- ajax+php打造進(jìn)度條代碼[readyState各狀態(tài)說(shuō)明]
- AJax 學(xué)習(xí)筆記二(onreadystatechange的作用)
- AJAX(XMLHttpRequest.status)狀態(tài)碼
- Ajax 給 XMLHttpReq.onreadystatechange傳遞參數(shù)
- javascript學(xué)習(xí)筆記(七)Ajax和Http狀態(tài)碼
- 探討Ajax中有關(guān)readyState(狀態(tài)值)和status(狀態(tài)碼)的問(wèn)題
相關(guān)文章
javascript中call,apply,callee,caller用法實(shí)例分析
這篇文章主要介紹了javascript中call,apply,callee,caller用法,結(jié)合實(shí)例形式分析了javascript中call,apply,callee,caller功能、使用方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-07-07
JS實(shí)現(xiàn)網(wǎng)頁(yè)上隨機(jī)產(chǎn)生超鏈接地址的方法
這篇文章主要介紹了JS實(shí)現(xiàn)網(wǎng)頁(yè)上隨機(jī)產(chǎn)生超鏈接地址的方法,涉及JavaScript隨機(jī)數(shù)的相關(guān)使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
JScript中的undefined和"undefined"的區(qū)別
JScript中的undefined和"undefined"的區(qū)別...2007-03-03
初步使用bootstrap快速創(chuàng)建頁(yè)面
初步嘗試使用Express搭建了一個(gè)Web框架,那么接下來(lái)就是要在該框架下寫上自己的頁(yè)面,快速創(chuàng)建頁(yè)面這里選擇了bootstrap前端框架,通過(guò)它即使你不太懂前端設(shè)計(jì),寫出來(lái)的頁(yè)面也不會(huì)太難看,感興趣的小伙伴們可以參考一下2016-03-03
javascript Table 中2個(gè)列(TD)的交換實(shí)現(xiàn)代碼
非常不錯(cuò)的用js控制talbe中td的位置的實(shí)現(xiàn)代碼。2009-02-02
js封裝成插件_Canvas統(tǒng)計(jì)圖插件編寫實(shí)例
下面小編就為大家?guī)?lái)一篇js封裝成插件_Canvas統(tǒng)計(jì)圖插件編寫實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09

