關(guān)于IE下AJAX的問題探討
更新時間:2014年03月10日 11:26:49 作者:
在IE下,AJAX請求得到響應(yīng)后,回調(diào)函數(shù)onreadystatechange是在全局環(huán)境下被調(diào)用的,而在標(biāo)準(zhǔn)瀏覽器下,其執(zhí)行上下文是XMLHttpRequest對象
今天JS練手的時候,想封裝一個發(fā)送AJAX請求的對象,當(dāng)然,是想要兼容全瀏覽器的。代碼如下:
var Ajax = {
xhr: null,
callback: null,
XMLHttp: function() {
var xmlhttp;
//標(biāo)準(zhǔn)瀏覽器
if(window.XMLHttpRequest) {
try {
xmlhttp = new XMLHttpRequest();
}
catch(e) {
alert('Unknown Ajax Error');
//console.log('Unknown Ajax Error');
}
}
//IE瀏覽器
else {
if(window.ActiveXObject) {
try {
xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
}
catch(e) {
try {
xmlhttp = new ActiveXObject('MSXML2.XMLHTTP');
}
catch(e) {
alert('Unknown Ajax Error');
//console.log('Unknown Ajax Error');
}
}
}
}
return xmlhttp;
},
connect: function(paramsObj) {
var PO = paramsObj;
//判斷傳參合法性
if(!(PO instanceof Object)) {
alert('Ajax params illegal');
//console.log('Ajax params illegal');
return false;
}
else if(!(PO.url&&PO.method&&PO.callback)) {
return false;
}
//初始化內(nèi)部參數(shù)
this.xhr = this.XMLHttp();
this.callback = PO.callback;
//遍歷params對象并生成url參數(shù)
var requestParams = '';
if(PO.params) {
for(key in Po.params) {
requestParams += '&' + key + '=' + params[key];
}
requestParams = requestParams.substr(1);
}
//發(fā)起Ajax請求
try {
var xhr = this.xhr;
xhr.onreadystatechange = this.response;
//POST請求處理
if(PO.method.toLowerCase()=='post') {
xhr.open('POST',PO.url,true);
xhr.send(requestParams);
}
//GET請求處理
else if(PO.method.toLowerCase()=='get') {
xhr.open('GET',PO.url+'?'+requestParams,true);
xhr.send(null);
}
}
catch(e) {
this.callback(null,-1);
}
},
response: function() {
// 此段代碼在全瀏覽器下測試通過
// if(Ajax.xhr.readyState==4) {
// if(Ajax.xhr.status=='200') {
// Ajax.callback(Ajax.xhr.responseText);
// }
// else {
// Ajax.callback(null,Ajax.xhr.status);
// }
// }
//
// 下面的代碼在IE下失效(無報錯,請求有相應(yīng),卻沒有返回結(jié)果),其它瀏覽器無此問題
if(this.readyState==4) {
if(this.status=='200') {
Ajax.callback(this.responseText);
}
else {
Ajax.callback(null,this.status);
}
}
}
};
//Ajax實例
Ajax.connect({
url: 'test.html',
method: 'GET',
callback: function(data,err) {
if(data!=null) {
alert(data);
// console.log(data);
}
else {
alert(err);
// console.log(err);
}
}
});
問題描述: 大家看一下我代碼中有一塊注釋掉的代碼,那塊代碼是在全瀏覽器下測試通過的。而沒有注釋掉的代碼是有問題的代碼,具體表現(xiàn):
在Chrome,F(xiàn)irefox,Opera,Safari下測試通過,在IE6、7(IE8+沒有測試)下的表現(xiàn)是:沒有報錯,也沒有返回結(jié)果。
對比上下兩塊代碼的不同,我想有兩個可能,一個是this指向的問題,一個是IE下onreadystatechange函數(shù)執(zhí)行的上下文環(huán)境有區(qū)別于其它瀏覽器。但是現(xiàn)在又無法確定問題,IE6、7下的JS調(diào)試又挺困難的(試了firebug-lite,但是沒有想象中的好用,而且這個Ajax對象在firebug-lite下調(diào)用卻成功了,有點糊涂)
解決過程:
其實測試方法很簡單。主要是頭腦一發(fā)熱沒想到,吃了個飯回來就恍然大悟。
其實JS在處理this指向不明的問題的時候,可以嘗試使用this instanceof Object這類判斷去了解它指向的是一個什么類型的變量。而對于判斷是否為全局調(diào)用,則可以使用this===window。在這里我用的就是這個方法。
在代碼出現(xiàn)問題的那一塊,我們可以試著插入一段:
alert(this instanceof Object);
結(jié)果發(fā)現(xiàn),在IE6下,返回為false!一目了然!在IE下才可能出現(xiàn)如此詭異的返回值!證明什么?也就是說函數(shù)的執(zhí)行上下文并非是對象!如此一來,在IE下就只能想到window對象了,要知道IE向來都是奇葩。你們標(biāo)準(zhǔn)瀏覽器說window對象是對象,我就偏不認(rèn)。你還在懷疑我的看法?那何不試試?
alert(this===window);
結(jié)果是true!怎么樣?沒話說了吧?所以這樣,問題就明朗了:
在IE下,AJAX請求得到響應(yīng)后,回調(diào)函數(shù)onreadystatechange是在全局環(huán)境下被調(diào)用的。而在標(biāo)準(zhǔn)瀏覽器下,其執(zhí)行上下文是XMLHttpRequest對象。故造成了我這次的“事故”。
復(fù)制代碼 代碼如下:
var Ajax = {
xhr: null,
callback: null,
XMLHttp: function() {
var xmlhttp;
//標(biāo)準(zhǔn)瀏覽器
if(window.XMLHttpRequest) {
try {
xmlhttp = new XMLHttpRequest();
}
catch(e) {
alert('Unknown Ajax Error');
//console.log('Unknown Ajax Error');
}
}
//IE瀏覽器
else {
if(window.ActiveXObject) {
try {
xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
}
catch(e) {
try {
xmlhttp = new ActiveXObject('MSXML2.XMLHTTP');
}
catch(e) {
alert('Unknown Ajax Error');
//console.log('Unknown Ajax Error');
}
}
}
}
return xmlhttp;
},
connect: function(paramsObj) {
var PO = paramsObj;
//判斷傳參合法性
if(!(PO instanceof Object)) {
alert('Ajax params illegal');
//console.log('Ajax params illegal');
return false;
}
else if(!(PO.url&&PO.method&&PO.callback)) {
return false;
}
//初始化內(nèi)部參數(shù)
this.xhr = this.XMLHttp();
this.callback = PO.callback;
//遍歷params對象并生成url參數(shù)
var requestParams = '';
if(PO.params) {
for(key in Po.params) {
requestParams += '&' + key + '=' + params[key];
}
requestParams = requestParams.substr(1);
}
//發(fā)起Ajax請求
try {
var xhr = this.xhr;
xhr.onreadystatechange = this.response;
//POST請求處理
if(PO.method.toLowerCase()=='post') {
xhr.open('POST',PO.url,true);
xhr.send(requestParams);
}
//GET請求處理
else if(PO.method.toLowerCase()=='get') {
xhr.open('GET',PO.url+'?'+requestParams,true);
xhr.send(null);
}
}
catch(e) {
this.callback(null,-1);
}
},
response: function() {
// 此段代碼在全瀏覽器下測試通過
// if(Ajax.xhr.readyState==4) {
// if(Ajax.xhr.status=='200') {
// Ajax.callback(Ajax.xhr.responseText);
// }
// else {
// Ajax.callback(null,Ajax.xhr.status);
// }
// }
//
// 下面的代碼在IE下失效(無報錯,請求有相應(yīng),卻沒有返回結(jié)果),其它瀏覽器無此問題
if(this.readyState==4) {
if(this.status=='200') {
Ajax.callback(this.responseText);
}
else {
Ajax.callback(null,this.status);
}
}
}
};
//Ajax實例
Ajax.connect({
url: 'test.html',
method: 'GET',
callback: function(data,err) {
if(data!=null) {
alert(data);
// console.log(data);
}
else {
alert(err);
// console.log(err);
}
}
});
問題描述: 大家看一下我代碼中有一塊注釋掉的代碼,那塊代碼是在全瀏覽器下測試通過的。而沒有注釋掉的代碼是有問題的代碼,具體表現(xiàn):
在Chrome,F(xiàn)irefox,Opera,Safari下測試通過,在IE6、7(IE8+沒有測試)下的表現(xiàn)是:沒有報錯,也沒有返回結(jié)果。
對比上下兩塊代碼的不同,我想有兩個可能,一個是this指向的問題,一個是IE下onreadystatechange函數(shù)執(zhí)行的上下文環(huán)境有區(qū)別于其它瀏覽器。但是現(xiàn)在又無法確定問題,IE6、7下的JS調(diào)試又挺困難的(試了firebug-lite,但是沒有想象中的好用,而且這個Ajax對象在firebug-lite下調(diào)用卻成功了,有點糊涂)
解決過程:
其實測試方法很簡單。主要是頭腦一發(fā)熱沒想到,吃了個飯回來就恍然大悟。
其實JS在處理this指向不明的問題的時候,可以嘗試使用this instanceof Object這類判斷去了解它指向的是一個什么類型的變量。而對于判斷是否為全局調(diào)用,則可以使用this===window。在這里我用的就是這個方法。
在代碼出現(xiàn)問題的那一塊,我們可以試著插入一段:
alert(this instanceof Object);
結(jié)果發(fā)現(xiàn),在IE6下,返回為false!一目了然!在IE下才可能出現(xiàn)如此詭異的返回值!證明什么?也就是說函數(shù)的執(zhí)行上下文并非是對象!如此一來,在IE下就只能想到window對象了,要知道IE向來都是奇葩。你們標(biāo)準(zhǔn)瀏覽器說window對象是對象,我就偏不認(rèn)。你還在懷疑我的看法?那何不試試?
alert(this===window);
結(jié)果是true!怎么樣?沒話說了吧?所以這樣,問題就明朗了:
在IE下,AJAX請求得到響應(yīng)后,回調(diào)函數(shù)onreadystatechange是在全局環(huán)境下被調(diào)用的。而在標(biāo)準(zhǔn)瀏覽器下,其執(zhí)行上下文是XMLHttpRequest對象。故造成了我這次的“事故”。
相關(guān)文章
AJAX的原理—如何做到異步和局部刷新【實現(xiàn)代碼】
如何做到異步和局部刷新?下面小編就為大家?guī)硪黄狝JAX的原理—如何做到異步和局部刷新【實現(xiàn)代碼】。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05ajax提交手機號去數(shù)據(jù)庫驗證并返回狀態(tài)值
這篇文章主要為大家詳細(xì)介紹了ajax提交手機號去數(shù)據(jù)庫驗證并返回狀態(tài)值的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01利用promise及參數(shù)解構(gòu)封裝ajax請求的方法
這篇文章主要介紹了利用promise及參數(shù)解構(gòu)封裝ajax請求的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-01-01AJAX在GB2312的中文編碼傳輸 AJAX特殊字符編碼正確方法
此文章為個人總結(jié),花了近半天時間搜索、試驗,在網(wǎng)上看到很多關(guān)于AJAX編碼問題,不一而足2010-01-01