encodeURI() 為什麼URI要編碼?
encodeURI 可以為URI編碼,使其符合URI規範。
URI是Uniform Resource Identifier 的縮寫,中文翻譯為 "統一資源標誌符" 。
為什麼要對URI編碼,什麼時候用的到URI編碼?
如果對URI編碼很陌生,那我們先來看個例子,看看URI編碼跟我們有多常接觸。
先打開google的網頁:
在搜尋欄輸入"維克的煩惱",按下google搜尋,等結果出來。
老實說我滿期待你看到這個部落格在第一名的位置 XD"。
不過這不是現在的重點。我們把視線移到位址欄。
把它複製下來:
https://www.google.com.tw/#hl=zh-TW&tbo=d&site=&source=hp&q=%E7%B6%AD%E5%85%8B%E7%9A%84%E7%85%A9%E6%83%B1&oq=%E7%B6%AD%E5%85%8B%E7%9A%84%E7%85%A9%E6%83%B1&gs_l=hp.12...36398.36398.0.37530.1.1.0.0.0.0.34.34.1.1.0.pchsnhae..0.0...1c.1.Y1Fa80-ocAE&bav=on.2,or.r_gc.r_pw.&bvm=bv.1355325884,d.dGY&fp=152a56cbfacd4238&bpcl=39967673&biw=1843&bih=887
好長一串。現在來看一下q=後面的那一串紅色編碼。
var str="%E7%B6%AD%E5%85%8B%E7%9A%84%E7%85%A9%E6%83%B1" ;
document.writeln(decodeURI(str));
輸出=>維克的煩惱。
沒錯這串紅色編碼就是對"維克的煩惱"進行encodeURI編碼的結果。所以說encodeURI就藏在生活中..XD"
(事實上對於參數的URI編碼,使用encodeURIComponent()才是正確的,可以避免功能性的字符造成URI的混淆,
不過這裡沒有使用功能性字符,所以其實也沒啥差。)
現在來點耐心,看看個URI簡短介紹吧,好吧!如果還是不習慣URI這名稱的話,其實可以暫時把它想成是網址...
雖然URI不只被用在網址的表現,但是身為一個WEB前端應用程式開發人員...........業餘的..我...
最常接觸到的應該也是網址了吧。
URI短介:
URI可以被當成URL(統一資源定位符)或URN(统一资源名),或是兩個合起來。
URL通常代表著位址,URN則是資源的名字。
絕對URI( absolute URI )的語法如下:
<scheme>:<scheme-specific-part>
不過我們常用的網址是URI的一個子集,一般型URI(generic URI 是這樣翻譯嗎==? 文章尾端有附原文),
語法如下:
<scheme>://<authority><path>?<query>
拿這文章的網址當個例子吧:
http://www.victsao.com/blog/81-javascript/89-javascript-encodeuri-uri
scheme:http
authority:www.victsao.com
path:/blog/81-javascript/89-javascript-encodeuri-uri
query:尷尬了!沒有耶!這啥爛例子。
好吧來看一下RFC3986 附的的例子吧,一次來兩個:
來自:http://tools.ietf.org/html/rfc3986
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/\_________/ \_________/ \__/
| | | | |
scheme authority path query fragment
| ____________________|__
/ \ / \
urn:example:animal:ferret:nose
URI編碼:
URI允許的字元包括:大小寫英文字母,數字,標記(mark),保留字跟跳脫編碼。
標記:- _ . ! ~ * ' ( )
保留字:; / ? : @ & = + $ ,
跳脫編碼:%加兩個16進位編碼。例:%AB、%FB
注意:%會出現在URI中,但它本身需要被編碼。
看得很混亂看看例子吧:
標記:
var str="-_.!~*'()";
var a=encodeURI(str);
document.writeln(a); 輸出==>-_.!~*'()
var b=encodeURIComponent(str);
document.writeln(b); 輸出==>-_.!~*'()
保留字:
var str=";/?:@&=+$,";
var a=encodeURI(str);
document.writeln(a); 輸出==>;/?:@&=+$,
var b=encodeURIComponent(str);
document.writeln(b); 輸出==>%3B%2F%3F%3A%40%26%3D%2B%24%2C
URI拒絕字元:
var str="<>#%<>";
var a=encodeURI(str);
document.writeln(a); 輸出==>%3C%3E#%25%3C%3E 注意: #沒被編碼
var b=encodeURIComponent(str);
document.writeln(b); 輸出==>%3C%3E%23%25%3C%3E
何時會使用到encodeURI()與encodeURIComponent():
最常接觸的大概就是AJAX吧,AJAX就是用傳遞網址來要求資料。
看個例子吧:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>JSON/Atom Custom Search API Example</title>
</head>
<body onload="test();">
<div id="content"></div>
<script type="text/javascript">
var xmlhttp;
xmlhttp = new XMLHttpRequest(); //舊型IE不支援這作法
function showwho() {
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById('content').innerHTML = xmlhttp.responseText;
}
}
function test() {
var name = '維克';
url = 'test.php?who=' + name + "&time=" + new Date().getTime();
xmlhttp.open('GET', url, true);
xmlhttp.onreadystatechange = showwho;
xmlhttp.send(null);
}
</script>
</body>
</html>
PHP:
<?php
echo($_GET['who']);
?>
這在IE9測試的結果,會出現亂碼!但在chrome是正常顯示的。
位時麼會這樣?
因為"維克"不是個URI的標準字元,PHP的GET認為所有非法URI字元都應該已經被編碼。
所以在處理時也會在解碼回來。沒編碼過的字元被解碼傳回來,結果就變亂碼了。
那為啥Chrome可以正常顯示?
因為Chrome在傳遞網址時會自動將非法的URI字元編碼!
聽說IE經過設定後也可以自動編碼URI非法字元,
但是即便如此瀏覽器依賴的程式設計並不是個好主意。
確保的做法是,對"維克"做encodeURIComponent ()的動作。
var name = '維克';
name=encodeURIComponent(name);
然後再傳出去!
傳遞表單時其實也會用到URI編碼。
表單傳遞其實有內建編碼傳遞方式,application/x-www-form-urlencoded
這邊碼方式並不標準,但接受度很廣..
有空閒在來多寫一些例子,先這樣吧!~~~~
沒寫到的:
1. encodeURI()跟encodeURIComponent ()都認定輸入字串為UTF-8做編碼。
並不作轉碼的動作,請確定你給他的字串是UTF-8編碼。
2.ECMA-262 5.1 Edition June/2011 支援的URI版本是RFC2396 而不是較新的RFC3986
3.在google 例子中出現的#是代表片段標識符
4.URI其實還滿複雜的,我都不太懂==",反正encodeURI就對了。
來自http://tools.ietf.org/html/rfc2396的部分原文:
An absolute URI contains the name of the scheme being used (<scheme>)
followed by a colon (":") and then a string (the <scheme-specific-
part>) whose interpretation depends on the scheme.
The URI syntax does not require that the scheme-specific-part have
any general structure or set of semantics which is common among all
URI. However, a subset of URI do share a common syntax for
representing hierarchical relationships within the namespace. This
"generic URI" syntax consists of a sequence of four main components:
<scheme>://<authority><path>?<query>