解決URL傳中文參數亂碼問題及原理

解決方案

在前臺,對URL的中文參數執行兩次encodeURI:

var param = encodeURI(encodeURI("中文"));

後臺取數據時使用 URLDecoder進行解碼:

String param = (String)request.getParameter("param");
param = URLDecoder.decode(param,"UTF-8");

原理解析

前臺傳的參數“中文”:

第一次encodeURI,按照utf-8方式獲取字節數組變成[-28,-72,-83,-34,-67,-41],對字節碼數組進行遍歷,把每個字節轉化成對應的16進制數,這樣就變成了[e4,b8,ad,e6,96,87],最後變成[%e4,%b8,%ad,%e6,%96,%87]。

第二次encodeURI,把數組最後變成[%25e4,%25b8,%25ad,%25e6,%2596,%2587]然後就把處理後的數據[%25e4,%25b8,%25ad,%25e6,%2596,%2587]發往後臺服務器端。

當服務器調用getParameter方法獲取參數時,服務器將讀取前臺傳過來的[%25e4,%25b8,%25ad,%25e6,%2596,%2587],然後執行一次URLdecode操作,然後將操作的結果[%e4,%b8,%ad,%e6,%96,%87]返回給getParameter,此時再執行一次URLdecode就可以把數據還原成最初頁面發送過來的“中文”了。

URL編碼與兩次encodeURI

當使用地址欄提交查詢參數時,如果不編碼,非英文字符會按照操作系統的字符集進行編碼提交到服務器,服務器會按照配置的字符集進行解碼,所以如果兩者不一致就會導致亂碼。

encodeURI函數採用UTF-8對URL進行編碼,所以如果服務器在進行解碼時使用的是其他的編碼方式就會出現亂碼,默認的服務器配置的解碼字符集都不是UTF-8,所以大部分情況下地址欄提交中文查詢參數時會產生亂碼;針對這種情況,可以連續使用兩次encodeURI在客戶端(主要指瀏覽器)對非英文字符進行編碼,然後在服務端使用Java.NET.URLDecoder(String."UTF-8")解碼,即可得到正確的中文。

如果只進行一次encodeURI,得到的是UTF-8形式的URL,服務器端通過request.getParameter()解碼查詢參數(通常是iso-8859-1)就會得到亂碼。

如果進行兩次encodeURI,第一次編碼得到的是UTF-8形式的URL,第二次編碼得到的依然是UTF-8形式的URL,但是在效果上相當於首先進行了一次UTF-8編碼(此時已經全部轉換爲ASCII字符),再進行了一次iso-8859-1編碼,因爲對英文字符來說UTF-8編碼和ISO-8859-1編碼的效果相同。在服務器端,首先通過request.getParameter()自動進行第一次解碼(可能是gb2312,gbk,utf-8,iso-8859-1等字符集,對結果無影響)得到ascii字符,然後再使用UTF-8進行第二次解碼,通常使用java.net.URLDecoder("","UTF-8")方法。

兩次編碼兩次解碼的過程爲:

UTF-8編碼->UTF-8(iso-8859-1)編碼->iso-8859-1解碼->UTF-8解碼,編碼和解碼的過程是對稱的,所以不會出現亂碼。

encodeURL函數主要是來對URI來做轉碼,它默認是採用的UTF-8的編碼.
. UTF-8編碼的格式:一個漢字來三個字節構成,每一個字節會轉換成16進制的編碼,同時添加上%號

 

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