XMLHttpRequest讀取中文網頁時返回亂碼的解決辦法

XMLHttpRequest讀取中文網頁時返回亂碼的解決辦法

XMLHttpRequest 默認是用UTF-8 傳遞數據。當服務端的返回數據是UTF-8編碼的時候,它工作得很好(開發web應用,當服務端和客戶端以及數據庫統一使用UTF-8編碼可以有效的避免亂碼問題)。如果服務端設置了正確的Content-Type Response Header以及編碼信息,那麼XmlHttpRequest也可以正確工作。

可是當使用XMLHttpRequest讀取中文網頁內容時, 如果服務端的程序沒有設置Content-Type Response Header,或者Header沒有設置編碼類型,那麼我們訪問responseText屬性的時候就可能遭遇亂碼。如以下代碼用XMLHttpRequest獲取雅虎中國網站的星座站首頁:

xmlhttp = getXMLHttpRequest();
var url = "http://cn.astrology.yahoo.com/";
xmlhttp.open("GET", url, true);
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4)
    if (xmlhttp.status == 200)
        alert(xmlhttp.responseText);
};
xmlhttp.send(null);

縱使yahoo中國這樣專業的網站,對web標準的支持還很不徹底,彈出的html源碼中充斥不符合web標準的html標籤,當然還有已預見的亂碼。

同樣遺憾的是,FireFox 和 IE 的解決方法也是南轅北轍

FireFox

FireFox 的XMLHttpRequest對象支持overrideMimeType方法,可以指定返回數據的編碼類型,利用該方法可以解決中文亂碼,前面的代碼修改如下:

xmlhttp = getXMLHttpRequest();
var url = "http://cn.astrology.yahoo.com/";
xmlhttp.open("GET", url, true);
xmlhttp.overrideMimeType("text/html;charset=gb2312");//設定以gb2312編碼識別數據
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4)
    if (xmlhttp.status == 200)
        alert(xmlhttp.responseText);
};
xmlhttp.send(null);

Internet Explorer

IE不支持overrideMimeType方法,並且只能用一種很蹩腳的方法來解決,此時需要引入一個雜交的函數:

function gb2utf8(data){
	var glbEncode = [];
	gb2utf8_data = data;
	execScript("gb2utf8_data = MidB(gb2utf8_data, 1)", "VBScript");
	var t=escape(gb2utf8_data).replace(/%u/g,"").replace(/(.{2})(.{2})/g,"%$2%$1").replace(/%([A-Z].)%(.{2})/g,"@$1$2");
	t=t.split("@");
	var i=0,j=t.length,k;
	while(++i<j) {
		k=t[i].substring(0,4);
		if(!glbEncode[k]) {
			gb2utf8_char = eval("0x"+k);
			execScript("gb2utf8_char = Chr(gb2utf8_char)", "VBScript");
			glbEncode[k]=escape(gb2utf8_char).substring(1,6);
		}
		t[i]=glbEncode[k]+t[i].substring(4);
	}
	gb2utf8_data = gb2utf8_char = null;
	return unescape(t.join("%"));
}

xmlhttp = getXMLHttpRequest(); var url = "http://cn.astrology.yahoo.com/"; xmlhttp.open("GET", url, true); xmlhttp.onreadystatechange = function(){ if (xmlhttp.readyState == 4) if (xmlhttp.status == 200) alert(gb2utf8(xmlhttp.responseBody)); //注意這裏要用responseBody }; xmlhttp.send(null);

gb2utf8函數直接解析XMLHttpRequest返回的二進制數據,其中要利用execScript方法來執行VBScript的函數。所以說是一個雜交的函數。感謝>>blueidea論壇 提供的算法。

雖然有了解決的辦法,但形式醜陋,而且不符合web標準。所以應該在編程中儘量避免,如果是開發web應用,應儘量使用UTF-8編碼,或者在服務端設置正確的編碼信息。至於以上範例,有盜取其他網站內容的嫌疑,更是不爲提倡。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章