2010-04-20 23 views
3

我正在開發一個firefox插件,並提取網頁爲用戶做一些分析。問題是,當我嘗試獲取(XMLHttpRequest)不是utf-8編碼的頁面時,我看到的字符串被搞亂了。例如希伯來語頁面使用windows-1125或中文頁面使用gb2312。使用Javascript將ISO/Windows字符集轉換爲UTF-8

我已經試過如下:

var uDecoder=Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].getService(Components.interfaces.nsIScriptableUnicodeConverter); 
uDecoder.charset="windows-1255"; 
alert(xhr.responseText); 

var decoder=Components.classes["@mozilla.org/intl/utf8converterservice;1"].getService(Components.interfaces.nsIUTF8ConverterService); 

alert(decoder.convertStringToUTF8(xhr.responseText,"WINDOWS-1255",true)); 

我也試過escape/unescape/encodeURIComponent

任何想法?

回答

4

一旦XMLHttpRequest試圖使用UTF-8解碼非UTF-8字符串,您已經丟失了。頁面中不是有效的UTF-8序列的字節序列已被破壞(通常轉換爲,即U + FFFD替換字符)。沒有任何重新編碼/解碼的數量會讓他們回來。

指定Content-Type: text/html;charset=something HTTP標頭的頁面應該沒問題。頁面沒有真正的HTTP頭,但確實有<meta>版本不會,因爲XMLHttpRequest不知道解析HTML,所以它不會看到元。如果你事先知道你想要的字符集,你可以告訴XMLHttpRequest,它會使用它:

xhr.open(...); 
xhr.overrideMimeType('text/html;charset=gb2312'); 
xhr.send(); 

(這是當前非標準化的Mozilla擴展。)

如果你不知道在提前的字符集中,您可以請求該頁面一次,破解<meta>字符集的標題,解析出來並用新字符集再次請求。

從理論上講,你可以得到一個請求二元響應:

xhr.overrideMimeType('text/html;charset=iso-8859-1'); 

,然後轉換從字節-AS-字符爲UTF-8。然而,iso-8859-1不會爲這個工作,因爲在瀏覽器解釋該字符集爲真的是Windows代碼頁1252

也許你可以使用另一種代碼頁,每一個字節映射到一個字符,冗長的文字的負載替代品將該代碼頁中的每個字符映射到實際的ISO-8859-1字符,然後進行轉換。大多數編碼不會每字節映射字節,但阿拉伯語(cp1256)可能是這個候選人?

+0

感謝 - 工作... 我想你是寫我將不得不兩次取非UTF - 8頁... – Amir 2010-04-20 11:49:41

+0

增加了一些想法,以避免第二次取...不是很好的想法,但可能可行。 – bobince 2010-04-20 11:51:03