分类: Python/Ruby
2010-12-02 16:51:26
因為噗浪朋友的,讓我興起了想要整理一些關於 URLEncode 的問題,整理一下才發現每個語言都有不同的函式來處理關於 URLEncode 的問題。
先說為什麼需要作 URLEncode,規範了哪些字元是作為保留字(如:!、@、/、?等),如果URL中使用到了這些保留字,就必須將它編碼為「%HEXHEX」的形式,舉例來說,「空白字元」的 ASCII code 是32,所以會被編碼為 %20,而其它 non-ASCII 字元(如:中文字)則以 UTF-8 字元編碼後的位元組來編碼成 %HEXHEX 的形式。
如果有一個字串是:「This is my **書本**」,根據 RFC 3986 的定義,作完 URL encode 之後應該會變成「This%20is%20my%20%2A%2A%E6%9B%B8%E6%9C%AC%2A%2A」。
那什麼時候會需要對文字作 URL encode 呢?比方說, 提供了一個分享網頁到個人塗鴨牆(Wall)的作法,那就是將欲分享的網頁URL,比方說是 ,只要將它作為參數(u傳給就可以了,但你千萬不能寫成:
,而是必須將它作 URL encode 之後,組合成:
這樣才是正確的。
若是你在瀏覽器的網址列直接輸入前者也會正確,那是因為瀏覽器會幫你作了 url encode
。
不過,在 RFC 3986 之前, 也有為 GET/POST 在傳遞參數時的 url encode 方式作定義,基本上也是 encode 成 %HEXHEX 的形式,保留字跟 RFC 3986 的有部份出入,不過就沒有限定一定是 UTF-8 的文字編碼了,而且還有一個重點--「空白字元」會被編碼成 + 而不是 %20。所以「This is a book」就會被編碼成「This+is+a+book」。
常用語言的函式庫因為有這樣的差異,所以開發人員在使用函式庫的時候常常會搞混什麼時候該用/不該用什麼函式,以 PHP 來說就分為兩組函式:
簡單地說就是以 HTTP 所使用的 application/x-www-form-urlencoded 的編碼規則,也就是會將空白字元編碼成 + 而不是%20。
按照 RFC 3986 所定義的方式來作編碼。
Python 版本的話就是:
會把空白字元編碼成 +
JavaScript 的 encodeURI 或是 encodeURIComponent (兩者僅相差一些保留字是否要作編碼,如 #)目前則是都使用 RFC 3986 的方式來作編碼,所以要作 application/x-www-form-urlencoded 的編碼時(AJAX POST),就要自己把 %20 替換成 + (jQuery 目前的程式碼就是這樣做的)
Java 的 java.net.URLEncoder.encode 這個 method 也是編碼成 application/x-www-form-urlencoded 的方式,如果要遵照 RFC 3986 的定義,則可以自行再把 + 替換成 %20 即可。