URL地址中的中文亂碼問題的解決

 在Restful類的服務設計中,常常會碰到須要在URL地址中使用中文做爲的參數的狀況,這種狀況下,通常都須要正確的設置和編碼中文字符信息。

1. 問題的引出javascript

在Restful的服務設計中,查詢某些信息的時候,通常的URL地址設計爲: get /basic/service? keyword=歷史 , 之類的URL地址。 可是,在實際的開發和使用中,確是有亂碼狀況的發生,在後臺的讀取keyword信息爲亂碼,沒法正確讀取。前端

2. 亂碼是如何產生的?java

因爲咱們利用URL傳遞參數這種方式是依賴與瀏覽器環境中的,也就是說URL及URL中包含的各個key=value格式的傳遞參數鍵值對參數是在瀏覽器地址欄中的處理原理處理相應編碼後傳遞至後臺進行解碼的。

因爲咱們沒有進行任何處理,此時javascript請求URL並傳參數存在中文時(也就是說輸入框中輸入中文時),對URL的中文參數進行編碼是按照瀏覽器機制進行編碼的。此時編碼存在亂碼問題。

3. 初次編碼, javascript中利用encodeURI()方法進行編碼。

利用encodeURI()在javascript中對中文URL參數進行編碼時,「測試」二字會被轉換爲「%E6%B5%8B%E8%AF%95」。 可是問題依然存在。緣由是在編碼後的字符串信息,瀏覽器機制會認爲「%」是一個轉義字符,瀏覽器會把地址欄URL中的傳遞的已轉換參數「%」與「%」之間的已轉義字符進行處理傳遞到後臺中。這樣會形成與實際通過encodeURI()編碼後的URL不符,由於瀏覽器誤認爲「%」是轉義字符字符了,它並未將「%」認爲是個普通字符。
4. 二次編碼,使用encodeURI
操做: encodeURI(encodeURI("/order?name=" + name));
處理後的URL不在是經過一次 encodeURI()轉換後的字符串」%E6%B5%8B%E8%AF%95「,而是通過上一步兩層encodeURI()處理URL處理後的字符串」%25E6%B255%258B%25E8%AF%2595「,經過再次編碼原有被瀏覽起解析爲轉義字符的」%「被再次編碼,轉換成了普通字符轉」%25「。
此時前端javascript代碼對帶有中文的URL編碼已經完成,並經過URL傳遞參數的方式傳遞到後臺等待處理,Action獲取到正常轉換切無亂碼的參數爲」%25E6%B255%258B%25E8%AF%2595「,此字符串對應的中文正是咱們輸入的」測試「二字。
5. 後臺如何正確解析中文字符信息?

進入後臺的信息,在通過二次encodeURI()以後,直接讀取是沒法後去正確的信息的。 須要繼續以下處理:ajax

URLDecoder.decode("chinese string","UTF-8")  複製代碼

URLDecoder的decode(String str,String ecn)方法有兩個參數,第一個參數爲待解碼的字符串,第二個參數爲解碼時的對應編碼。瀏覽器

6. encodeURI, encodeURIComponent, escapebash

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之類的轉義函數主要解決,特殊字符%,/之類的字符的轉義問題。

相關文章
相關標籤/搜索