引子 瀏覽器URl地址,上網一定會用到,但是瀏覽器地址有中文或者瀏覽器url參數操作的時候,經常會用到encodeURIComponent()和decodeURIComponent()以及encodeURI()等等。關於瀏覽器參數操作,請看文章http://www.haorooms.com/post ...
引子
瀏覽器URl地址,上網一定會用到,但是瀏覽器地址有中文或者瀏覽器url參數操作的時候,經常會用到encodeURIComponent()和decodeURIComponent()以及encodeURI()等等。關於瀏覽器參數操作,請看文章http://www.haorooms.com/post/js_url_canshu ,今天主要講講escape(),encodeURI(),encodeURIComponent()這幾個函數的用法和區別。
為啥會有瀏覽器編碼這一說法
一般來說,URL只能使用英文字母、阿拉伯數字和某些標點符號,不能使用其他文字和符號。比如,世界上有英文字母的網址 “h ttp://www.haorooms.com”, 但是沒有希臘字母的網址“h ttp://www.aβγ.com” (讀作阿爾法-貝塔-伽瑪.com)。這是因為網路標準RFC 1738做了硬性規定:
原文:"...Only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'()," [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL."
翻譯:“只有字母和數字[0-9a-zA-Z]、一些特殊符號“$-_.+!*'(),”[不包括雙引號]、以及某些保留字,才可以不經過編碼直接用於URL。”
這意味著,如果URL中有漢字,就必須編碼後使用。但是麻煩的是,RFC 1738沒有規定具體的編碼方法,而是交給應用程式(瀏覽器)自己決定。這導致“URL編碼”成為了一個混亂的領域。
下麵我們通過介紹escape(),encodeURI(),encodeURIComponent()來說說Javascript瀏覽器編碼方法。
出現瀏覽器編碼的幾種情況
1、網址路徑中包含漢字
如下圖:
h ttp://www.haorooms.com/您好, 在瀏覽器中顯示的是 h ttp://www.haorooms.com/%E6%82%A8%E5%A5%BD 自動對“你好”進行了編碼。要是我們瀏覽器地址中有中文的時候,就要用到url編碼了。
2、查詢字元串包含漢字
http://www.haorooms.com/search?keywords=您好
這樣包含查詢的的條件的時候,漢字也會被編碼。
3、Get方法生成的URL包含漢字
前面說的是直接輸入網址的情況,但是更常見的情況是,在已打開的網頁上,直接用Get或Post方法發出HTTP請求。
根據臺灣中興大學呂瑞麟老師的試驗,這時的編碼方法由網頁的編碼決定,也就是由HTML源碼中字元集的設定決定。
<meta http-equiv="Content-Type" content="text/html;charset=xxxx">
如果上面這一行最後的charset是UTF-8,則URL就以UTF-8編碼;如果是GB2312,URL就以GB2312編碼。
舉例來說,百度是GB2312編碼,Google是UTF-8編碼。因此,從它們的搜索框中搜索同一個詞“春節”,生成的查詢字元串是不一樣的。
百度生成的是%B4%BA%BD%DA,這是GB2312編碼。Google生成的是%E6%98%A5%E8%8A%82,這是UTF-8編碼。所以,結論3就是,GET和POST方法的編碼,用的是網頁的編碼。
4、Ajax調用的URL包含漢字
前面三種情況都是由瀏覽器發出HTTP請求,最後一種情況則是由Javascript生成HTTP請求,也就是Ajax調用。還是根據呂瑞麟老師的文章,在這種情況下,IE和Firefox的處理方式完全不一樣。
舉例來說,有這樣兩行代碼:
url = url + "?q=" +document.myform.elements[0].value; // 假定用戶在表單中提交的值是“春節”這兩個字
http_request.open('GET', url, true);
那麼,無論網頁使用什麼字元集,IE傳送給伺服器的總是“q=%B4%BA%BD%DA”,而Firefox傳送給伺服器的總是“q=%E6%98%A5%E8%8A%82”。也就是說,在Ajax調用中,IE總是採用GB2312編碼(操作系統的預設編碼),而Firefox總是採用utf-8編碼。
瀏覽器編碼的函數簡介escape(),encodeURI(),encodeURIComponent()
1、escape()
escape()是js編碼函數中最古老的一個。雖然這個函數現在已經不提倡使用了,但是由於歷史原因,很多地方還在使用它,所以有必要先從它講起。
實際上,escape()不能直接用於URL編碼,它的真正作用是返回一個字元的Unicode編碼值。比如“春節”的返回結果是%u6625%u8282,也就是說在Unicode字元集中,“春”是第6625個(十六進位)字元,“節”是第8282個(十六進位)字元。
例如:
javascript:escape("春節");
//輸出 "%u6625%u8282"
javascript:escape("hello word");
//輸出 "hello%20word"
還有兩個地方需要註意。
首先,無論網頁的原始編碼是什麼,一旦被Javascript編碼,就都變為unicode字元。也就是說,Javascipt函數的輸入和輸出,預設都是Unicode字元。這一點對下麵兩個函數也適用。
javascript:escape("\u6625\u8282");
//輸出 "%u6625%u8282"
javascript:unescape("%u6625%u8282");
//輸出 "春節"
javascript:unescape("\u6625\u8282");
//輸出 "春節"
其次,escape()不對“+”編碼。但是我們知道,網頁在提交表單的時候,如果有空格,則會被轉化為+字元。伺服器處理數據的時候,會把+號處理成空格。所以,使用的時候要小心。
2、encodeURI()
它著眼於對整個URL進行編碼,因此除了常見的符號以外,對其他一些在網址中有特殊含義的符號“; / ? : @ & = + $ , #”,也不進行編碼。編碼後,它輸出符號的utf-8形式,並且在每個位元組前加上%。
它對應的解碼函數是decodeURI()。
需要註意的是,它不對單引號'編碼。
3、encodeURIComponent()
最後一個Javascript編碼函數是encodeURIComponent()。與encodeURI()的區別是,它用於對URL的組成部分進行個別編碼,而不用於對整個URL進行編碼。
因此,“; / ? : @ & = + $ , #”,這些在encodeURI()中不被編碼的符號,在encodeURIComponent()中統統會被編碼。至於具體的編碼方法,兩者是一樣。
它對應的解碼函數是decodeURIComponent()。
encodeURIComponent()相比encodeURI()要更加徹底。
例如:
<html>
<body>
<script type="text/javascript">
var test1="http://www.haorooms.com/My first/";
var nn=encodeURI(test1);
var now=decodeURI(test1);
var test1="http://www.haorooms.com/My first/";
var bb=encodeURIComponent(test1);
var nnow=decodeURIComponent(bb);
</script>
</body>
</html>
輸出結果是:
http://www.haorooms.com/My%20first/
http://www.haorooms.com/My first/
http%3A%2F%2Fwww.haorooms.com%2FMy%20first%2F
http://www.haorooms.com/My first/
總結
escape()不能直接用於URL編碼,它的真正作用是返回一個字元的Unicode編碼值。比如"春節"的返回結果是%u6625%u8282,,escape()不對"+"編碼 主要用於漢字編碼,現在已經不提倡使用。
encodeURI()是Javascript中真正用來對URL編碼的函數。 編碼整個url地址,但對特殊含義的符號"; / ? : @ & = + $ , #",也不進行編碼。對應的解碼函數是:decodeURI()。
encodeURIComponent() 能編碼"; / ? : @ & = + $ , #"這些特殊字元。對應的解碼函數是decodeURIComponent()。
假如要傳遞帶&符號的網址,所以用encodeURIComponent()