本文是對(duì)在正常網(wǎng)絡(luò)請(qǐng)求的URL中哪些字符需要編碼,為什么需要編碼進(jìn)行了說(shuō)明
URI介紹
URI
是統(tǒng)一資源標(biāo)識(shí)的意思卦羡,通常我們所說(shuō)的URL
只是URI
的一種绿饵。典型URL
的格式如上面所示瓶颠。下面提到的URL
編碼,實(shí)際上應(yīng)該指的是URI
編碼吸祟。
為什么需要URL編碼
通常如果一樣?xùn)|西需要編碼,說(shuō)明這樣?xùn)|西并不適合傳輸屋匕。原因多種多樣,如Size過(guò)大吹埠,包含隱私數(shù)據(jù)疮装,對(duì)于URL
來(lái)說(shuō),之所以要進(jìn)行編碼刷袍,是因?yàn)?code>URL中有些字符會(huì)引起歧義樊展。
例如URL
參數(shù)字符串中使用key=value
鍵值對(duì)這樣的形式來(lái)傳參,鍵值對(duì)之間以&符號(hào)分隔雷酪,如/s?q=abc& ie=utf-8
涝婉。如果你的value字符串中包含了=或者&墩弯,那么勢(shì)必會(huì)造成接收URL
的服務(wù)器解析錯(cuò)誤,因此必須將引起歧義的&和= 符號(hào)進(jìn)行轉(zhuǎn)義锌钮,也就是對(duì)其進(jìn)行編碼引矩。
又如,Url的編碼格式采用的是ASCII碼兰吟,而不是Unicode茂翔,這也就是說(shuō)你不能在Url中包含任何非ASCII字符履腋,例如中文惭嚣。否則如果客戶端瀏覽器和服務(wù)端瀏覽器支持的字符集不同的情況下晚吞,中文可能會(huì)造成問(wèn)題谋国。
Url編碼的原則就是使用安全的字符(沒有特殊用途或者特殊意義的可打印字符)去表示那些不安全的字符。
哪些字符需要編碼
RFC3986文檔規(guī)定捌蚊,Url中只允許包含英文字母(a-zA-Z)近弟、數(shù)字(0-9)、-_.~4個(gè)特殊字符以及所有保留字符窗宦。
RFC3986文檔對(duì)Url的編解碼問(wèn)題做出了詳細(xì)的建議二鳄,指出了哪些字符需要被編碼才不會(huì)引起Url語(yǔ)義的轉(zhuǎn)變,以及對(duì)為什么這些字符需要編碼做出了相應(yīng)的解釋句占。
US-ASCII字符集中沒有對(duì)應(yīng)的可打印字符
Url中只允許使用可打印字符躯嫉。US-ASCII碼中的10-7F字節(jié)全都表示控制字符,這些字符都不能直接出現(xiàn)在Url中祈餐。同時(shí),對(duì)于80-FF字節(jié)(ISO-8859-1)哺壶,由于已經(jīng)超出了US-ACII定義的字節(jié)范圍山宾,因此也不可以放在Url中鳍徽。
保留字符
Url可以劃分成若干個(gè)組件,協(xié)議绷杜、主機(jī)、路徑等鞭盟。有一些字符(:/?#[]@)是用作分隔不同組件的。例如:冒號(hào)用于分隔協(xié)議和主機(jī)筝野,/用于分隔 主機(jī)和路徑粤剧,?用于分隔路徑和查詢參數(shù),等等途蒋。還有一些字符(!$&'()*+,;=)用于在每個(gè)組件中起到分隔作用的号坡,如=用于表示查詢參數(shù)中 的鍵值對(duì)梯醒,&符號(hào)用于分隔查詢多個(gè)鍵值對(duì)。當(dāng)組件中的普通數(shù)據(jù)包含這些特殊字符時(shí)畜隶,需要對(duì)其進(jìn)行編碼号胚。
不安全字符
還有一些字符,當(dāng)他們直接放在Url中的時(shí)候箱亿,可能會(huì)引起解析程序的歧義弃秆。這些字符被視為不安全字符,原因有很多脑豹。
空格
URL在傳輸?shù)倪^(guò)程衡查,或者用戶在排版的過(guò)程,或者文本處理程序在處理Url的過(guò)程击碗,都有可能引入無(wú)關(guān)緊要的空格们拙,或者將那些有意義的空格給去掉引號(hào)以及<>
引號(hào)和尖括號(hào)通常用于在普通文本中起到分隔Url的作用#
通常用于表示書簽或者錨點(diǎn)%
百分號(hào)本身用作對(duì)不安全字符進(jìn)行編碼時(shí)使用的特殊字符,因此本身需要編碼{}|\^[]~
某一些網(wǎng)關(guān)或者傳輸代理會(huì)篡改這些字符
需要注意的是砚婆,對(duì)于URL
中的合法字符,編碼和不編碼是等價(jià)的坷虑,但是對(duì)于上面提到的 這些字符迄损,如果不經(jīng)過(guò)編碼,那么它們有可能會(huì)造成Url語(yǔ)義的不同芹敌。因此對(duì)于Url而言氏捞,只有普通英文字符和數(shù)字冒版,特殊字符$-_.+!*'()
還有保留 字符,才能出現(xiàn)在未經(jīng)編碼的Url之中捆等。其他字符均需要經(jīng)過(guò)編碼之后才能出現(xiàn)在URL
中。
但是由于歷史原因续室,目前尚存在一些不標(biāo)準(zhǔn)的編碼實(shí)現(xiàn)。例如對(duì)于~
符號(hào)班缎,雖然RFC3986文檔規(guī)定她渴,對(duì)于波浪符號(hào)~
,不需要進(jìn)行URL
編碼沉唠,但是還是有很多老的網(wǎng)關(guān)或者傳輸代理會(huì)
如何對(duì)Url中的非法字符進(jìn)行編碼
Url編碼通常也被稱為百分號(hào)編碼(Url Encoding满葛,also known as percent-encoding),是因?yàn)樗木幋a方式非常簡(jiǎn)單嘀韧,使用%百分號(hào)加上兩位的字符——0123456789ABCDEF——代表一個(gè)字節(jié)的 十六進(jìn)制形式。Url編碼默認(rèn)使用的字符集是US-ASCII译蒂。例如a在US-ASCII碼中對(duì)應(yīng)的字節(jié)是0x61谊却,那么Url編碼之后得到的就 是%61,我們?cè)诘刂窓谏陷斎?code>http://g.cn/search?q=%61%62%63捕透,實(shí)際上就等同于在google上搜索abc了碴萧。
需要注意:
正常的使用encode的方法有兩個(gè),兩個(gè)編碼的格式所認(rèn)為的安全字符并不完全一致乒躺,具體如下:
- encodeURI(82個(gè))
!#$&'()*+,/:;=?@-._~0-9a-zA-Z
- encodeURIComponent(71個(gè))
!'()*-._~0-9a-zA-Z