1. 問題的引出
在Restful的服務設計中,查詢某些資訊的時候,一般的URL地址設計為: get /basic/service? keyword=歷史 , 之類的URL地址。 但是,在實際的開發和使用中,確是有亂碼情況的發生,在後臺的讀取keyword資訊為亂碼,無法正確讀取。
2. 亂碼是如何產生的?
進入後臺的資訊,在經過二次encodeURI()之後,直接讀取是無法後去正確的資訊的。 需要繼續如下處理:
URLDecoder.decode("chinese string","UTF-8") 複製程式碼
URLDecoder的decode(String str,String ecn)方法有兩個引數,第一個引數為待解碼的字串,第二個引數為解碼時的對應編碼。
6. encodeURI, encodeURIComponent, escape
6.1 escape()函式
escape() 函式可對字串進行編碼,這樣就可以在所有的計算機上讀取該字串。返回值:已編碼的 string 的副本。其中某些字元被替換成了十六進位制的轉義序列。
說明 :該方法不會對 ASCII 字母和數字進行編碼,也不會對下面這些 ASCII 標點符號進行編碼: - _ . ! ~ * ' ( ) 。其他所有的字元都會被轉義序列替換。所有的空格符、標點符號、特殊字元以及其他非ASCII字元都將被轉化成%xx格式的字元編碼(xx等於該字元在字符集表裡面的編碼的16進位制數字)。比如,空格符對應的編碼是%20。不會被此方法編碼的字元: @ * / +
6.2 encodeURI() 方法
把URI字串採用UTF-8編碼格式轉化成escape格式的字串。不會被此方法編碼的字元:! @ # $& * ( ) = : / ; ? + '6.3 encodeURIComponent() 方法
把URI字串採用UTF-8編碼格式轉化成escape格式的字串。與encodeURI()相比,這個方法將對更多的字元進行編碼,比如 / 等字元。所以如果字串裡面包含了URI的幾個部分的話,不能用這個方法來進行編碼,否則 / 字元被編碼之後URL將顯示錯誤。不會被此方法編碼的字元:! * ( ) '
因此,對於中文字串來說,如果不希望把字串編碼格式轉化成UTF-8格式的(比如原頁面和目標頁面的charset是一致的時候),只需要使用escape。如果你的頁面是GB2312或者其他的編碼,而接受引數的頁面是UTF-8編碼的,就要採用encodeURI或者encodeURIComponent。
說了這麼多,我常用的是下面的方案:
7. 另一種處理URL的中文亂碼方案(推薦使用)
請求端的中字元有encodeURI進行一次轉碼,如:
var url="/ajax?name="+encodeURI(name);
伺服器端程式碼:
name=new String(name.getBytes("iso8859-1"),"UTF-8");
注: name為獲得的字串,iso8859-1為專案的預設字元編碼,如果為中文編碼gbk,gb2312等則不用這一步進行處理.
分析: 經過程式驗證,結果可行的。 由此可知,瀏覽器本身預設的編碼方式是iso8859-1的方式,即使使用了encodeURI進行了utf-8編碼處理,主要的字串內容,比如ascii字元和可見字元都還是基於iso8859-1瀏覽器自身的字元。原因就是這些字元在編碼上和UTF-8字串是重合的。而encodeURI之類的轉義函式主要解決,特殊字元%,/之類的字元的轉義問題。