1. 程式人生 > >URL編碼中的空格問題

URL編碼中的空格問題

 

在調查一個錯誤的時候,偶然發現HTML頁面中的部分Link含有+,將tag反編譯了一下,發現是因為呼叫了java.net.URLEncoder的方法

public static String encode(String s, String enc)

從程式碼中可以很清晰的看到還特別照顧的將' '轉成了'+'。由於印象中的URL編碼規則應該是將空格轉為%20,就google了一把,結果發現很多人都遇到了這個問題,但基本都是語焉不詳。

花了1個多小時仔細搜尋了一遍,線索如下:

2、在W3C找到HTML標準的說明
http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4


在這裡清楚的看到編碼方式是根據ContextType的不同而區別對待的,在form的ContextType是[x-www-form-urlencoded]的時候會對form中的鍵/值對進行編碼,空格被轉義成+,其他字元按照[RFC1738]標準處理成%HH的形式。

3、回頭再看URLEncoder
發現該類的註釋中很明確的寫明瞭:
converting a String to the application/x-www-form-urlencoded MIME format

從以上的結果看來%20似乎只是在使用上的一個誤解,因為%20可以被解析成空格,所以就理所當然的認為空格應該被轉義為%20。

再進一步,對Java/.Net/JavaScript的相關函式進行下測試,結果發現Java(1.5)與.Net(2.0)的情況一致,但JavaScript的函式還是將空格轉換成了%20。看來這個問題的誤解完全來自於js的錯誤……

publicstaticvoid main(String[] args) {
    
try{
        System.out.println(URLEncoder.encode(
"Hello World","UTF-8"));
        System.out.println(URLDecoder.decode(
"Hello+World","UTF-8"));
        System.out.println(URLDecoder.decode(
"Hello%20World","UTF-8"));
    }
catch (UnsupportedEncodingException e) 
{
        e.printStackTrace();
    }

}
staticvoid Main()
{
      Console.WriteLine(HttpUtility.UrlEncode(
"Hello World"));
      Console.WriteLine(HttpUtility.UrlDecode(
"Hello World"));
      Console.WriteLine(HttpUtility.UrlDecode(
"Hello%20World")); 
}
<script language="JavaScript" type="text/javascript">
  document.write(escape(
'Hello World'+'<BR>');
  document.write(unescape(
'Hello+World'+'<BR>');
  document.write(unescape(
'Hello%20World'));
</script>