URI (Universal Resource Identifier) 通用資源識別字
URL (Uniform Resource Locator) 統一資源網址
escape(), encodeURI(), encodeURIComponent() 這三個函數都可以用來對 URI 進行編碼。
Why encoding? 不知其所以然?人活的好好的 幹嘛沒事要去編碼?
BECAUSE WE CAN !!!
因為資料(data)與特殊控制字元(control)對系統有不同的意義,如果資料與特殊控制字元無法完全隔離,就需要 脫離(escape) 來處理。
若資料與特殊控制字元分別存在於完全隔離的通道(例 FTP: port 21 control, port 20 data; packet format: byte0~3 length, byte4~ data; file: header, data...),其實在處理上也等同於 escape,只是方便性與效率的考量來決定用何種方式來區分 data / control。
一般為了方便(free format)與空間利用效率很難將資料與特殊控制字元完全隔離,其實只要有一點共識(協定、標準、規格)就不需要這麼(完全隔離)作。例如講電話的 "喂"、"Hello" 表示確認、通訊開始(SYN, ACK, STX, reset),若不知協定會發生錯誤,例如不懂日語的聽到 Moshimoshi(もしもし) 或無線電收到 CQ CQ 會把它當通話內容而回答。
中文(Big5)含有 0x5C 的字,含使用者造字部份(Unicode補完計畫):
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
日文(shift-JIS)含有 0x5C 的字:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
"\"\\\""
Why:
http 傳資料難免要 GET/POST。對 URL 編碼,以方便任何字串組成的 URL 可以 GET。
How:
1. 了解你的編碼對象,是 ASCII(Big5) 還是 Unicode(UTF-8)?
2. 了解前台(client, browser)的處理方式,(IE 設定選項) Always send URL as UTF-8(永遠將 URL 傳送成 UTF-8)。
3. 了解後台(CGI, JSP, PHP, ASP)的處理方式,哪些是特殊控制字元?是吃 ASCII 還是 Unicode?中文是否要另設 locale 處理? (Java,PHP)request.setCharacterEncoding("UTF-8");
(Delphi)THTTPRIO.HTTPWebNode.UseUTF8InHeader := true;
4. 若前台與後台的處理方式牽涉到系統,要再去了解系統是大端/小端?word 是幾位元?long 有多長?(Windows)Unicode 是 16-bit 還是 (Linux) 32-bit?
5. 了解編碼方法,選擇合適的方法來使用。不為保密的緣故而自己寫編碼函數,難驗證、難維護、效益低,純粹只是浪費時間。
6. 多種系統混合使用,就要注意 escape of escape。例如 C/Java/Perl/Python... 與 regular expression 字串的 escape 字元都是 \,因此 \ 本身會變成 ==> regular expression /\\/
==> regular expression in string "\\\\"
Delphi 字元 ' 會變成 ==> regular expression /\'/
==> regular expression in Delphi string '\'''
URL 編碼方法的比較
escape() 方法:
對傳入字串進行 "脫離(escape)" 編碼。所有的空格、標點符號、特殊字元以及其他非 ASCII 字元都將被轉化成 %xx 格式的編碼 (xx 等於該字元在字元集裡的 16 進制數值)。例如空格的編碼是 %20。
不會被此方法編碼的字元: * + - . / @ _
encodeURI() 方法:
把URI字串採用UTF-8編碼格式轉化成escape格式的字串。
不會被此方法編碼的字元: ! # $ & ' ( ) * + , - . / : ; = ? @ _ ~
encodeURIComponent() 方法:
把URI字串採用UTF-8編碼格式轉化成escape格式的字串。與encodeURI()相比,這個方法將對更多的字元進行編碼,比如 / 等字元。所以如果字串裡面包含了URI的幾個部分的話,不能用這個方法來進行編碼,否則 / 字元被編碼之後URL將顯示錯誤。
不會被此方法編碼的字元: ! ' ( ) * - . _ ~
因此,對於中文字串來說,如果不希望把字串編碼格式轉化成UTF-8格式的(比如原頁面和目標頁面的charset是一致的時候),只需要使用escape。如果你的頁面是GB2312或者其他的編碼,而接受參數的頁面是UTF-8編碼的,就要採用encodeURI或者encodeURIComponent。
另外,encodeURI/encodeURIComponent是在javascript1.5之後引進的,escape則在javascript1.0版本就有。
參考文章: Comparing escape(), encodeURI(), and encodeURIComponent()
http://xkr.us/articles/javascript/encode-compare/
Reference:
Copyright © 2007 Fun, Lung. All rights reserved.