https://blog.csdn.net/Lxd_0111/article/details/78028889
1. 為什么要URL編碼?
一句話(huà)總結(jié):是因?yàn)閁RL中有些字符會(huì)引起歧義。
比如某個(gè)url會(huì)是:https://localhost/search?name1=value1&name2=value2, name1=value1&name2=value2代表查詢(xún)參數(shù)。這樣在服務(wù)器收到這種字符串的時(shí)候,會(huì)用“&”分隔出每一個(gè)參數(shù),然后再用“=”來(lái)分隔出參數(shù)值。
客戶(hù)端到服務(wù)器端的概念上解析過(guò)程:
1. 在客戶(hù)端,上述URL被URL編碼(先轉(zhuǎn)成ASCII碼,再用16進(jìn)制表示)。我們展示一下參數(shù)編碼后的效果:
6E616D6531 3D 76616C756531 26 6E616D6532 3D 76616C756532
其中:=的ASCII碼是61,61轉(zhuǎn)成16進(jìn)制是3D,&符號(hào)的ASCII碼是38,38轉(zhuǎn)成16進(jìn)制就是26
2. 服務(wù)端收到URL后
服務(wù)器端在接收到該數(shù)據(jù)后就可以遍歷該字節(jié)流,首先一個(gè)字節(jié)一個(gè)字節(jié)的讀取,當(dāng)讀到3D這個(gè)字節(jié)的時(shí)候,服務(wù)器端就知道前面讀到的字節(jié)串表示一個(gè)key,繼續(xù)讀取,如果遇到了26,表示從剛才讀到的3D到26字節(jié)之間的字節(jié)串是上一個(gè)key的value,按照此方法就可以解析出客戶(hù)端傳過(guò)來(lái)的參數(shù)。
但是此時(shí)會(huì)有一個(gè)問(wèn)題:如果我的參數(shù)值中就包含=或者&這樣的特殊子字符的時(shí)候,該怎么辦。
比如說(shuō)“name1=value1”,其中value1的值是“va&lu=e1”,那么在傳輸過(guò)程中就會(huì)變成“name1=va&lu=e1”。用戶(hù)傳輸?shù)谋疽馐侵挥幸粋€(gè)鍵值對(duì),但是服務(wù)器端會(huì)解析成兩個(gè)鍵值對(duì),這樣就自然的產(chǎn)生了歧義。
所以由于要解決這個(gè)問(wèn)題,我們就需要對(duì)URL進(jìn)行編碼
2. 如何進(jìn)行URL編碼
一句話(huà)總結(jié):URL編碼只是簡(jiǎn)單的在特殊字符的各個(gè)字節(jié)(16進(jìn)制)前加上”%”即可。
例如,我們對(duì)會(huì)產(chǎn)生歧義的字符“name1=va&lu=e1”進(jìn)行編碼后的結(jié)果:name1=va%26lu%3De,這樣服務(wù)器會(huì)把緊跟在”%”后的字節(jié)當(dāng)成普通的字節(jié),不會(huì)把它當(dāng)成各個(gè)參數(shù)或鍵值對(duì)的分隔符。
(注意,這里為了方便name1=va這些并沒(méi)有進(jìn)行URL編碼,實(shí)際上要編碼的話(huà)所有的都會(huì)被編碼)
3. 為什么URL編碼的時(shí)候要用ASCII碼傳輸,可不可以用別的編碼?
當(dāng)然可以用別的編碼,你可以自己開(kāi)發(fā)一套編碼然后自己進(jìn)行解析。就像大部分國(guó)家都有自己的語(yǔ)言一樣。但是國(guó)家之間要怎么進(jìn)行交流呢,用英語(yǔ)吧,英語(yǔ)的使用范圍最廣。
4. URL編碼的原則就是:使用安全的字符(沒(méi)有特殊用途或者特殊意義的可打印字符)去表示那些不安全的字符
不安全字符:有一些字符,當(dāng)他們直接放在URL中的時(shí)候,可能會(huì)引起解析程序的歧義。這些字符被視為不安全的字符,原因有很多:
- 空格:URL在傳輸?shù)倪^(guò)程,或者用戶(hù)在排版的過(guò)程中,或者文本處理程序在處理URL的過(guò)程,都有可能引入無(wú)關(guān)緊要的空格,或者將那些有意義的空格給去掉。
- 引號(hào) 以及 <>:引號(hào)和尖括號(hào)通常用于在普通文本中起到分隔URL的作用。
- 符號(hào)# :通常用于表示書(shū)簽或者錨點(diǎn)。
- %:百分號(hào)本身用作對(duì)不安全的字符進(jìn)行編碼是使用的特殊字符,因此本身需要編碼。
- { } | \ ^ [ ] ’ ~:某一些網(wǎng)關(guān)或者傳輸代理會(huì)篡改這些字符
5. 哪些字符需要編碼
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)的解釋。