encodeURI() 為什麼URI要編碼?

Posted oliver1993

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了encodeURI() 為什麼URI要編碼?相关的知识,希望对你有一定的参考价值。

encodeURI 可以為URI編碼,使其符合URI規範。

URI是Uniform Resource Identifier 的縮寫,中文翻譯為 "統一資源標誌符" 。

為什麼要對URI編碼,什麼時候用的到URI編碼?

如果對URI編碼很陌生,那我們先來看個例子,看看URI編碼跟我們有多常接觸。

先打開google的網頁:

https://www.google.com.tw/

在搜尋欄輸入"維克的煩惱",按下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>

以上是关于encodeURI() 為什麼URI要編碼?的主要内容,如果未能解决你的问题,请参考以下文章

为什麼encodeURI/encodeURIComponent()要调用两次来进行转码?

Sql Server Report Service 的部署问题(Reporting Service 2014為什麼不需要IIS就可以運行)

encodeURIComponent和encodeURI的区别

encodeURI()和encodeURIComponent() 区别

JavaScript URI 编码与解码

encodeURI , encodeURIComponent , decodeURL , decodeURIComponent 转码与解码