使用瀏覽器進行Http網路請求時,若請求query中包含中文,中文會被編碼為 %+16進位制+16進位制
形式,但你真的深入瞭解過,為什麼要進行這種轉義編碼嗎?編碼的原理又是什麼?
例如,瀏覽器中進行百度搜尋“你好”時,連結地址會被自動編碼:
(編碼前)https://www.baidu.com/s?wd=你好
(編碼後)https://www.baidu.com/s?wd=%E4%BD%A0%E5%A5%BD
出現以上情況是網路請求前,瀏覽器對請求URL進行了URL編碼(URL Encoding)
。
URL編碼(URL Encoding)
:也稱作百分號編碼(Percent Encoding)
, 是特定上下文的統一資源定位符 URL的編碼機制。URL編碼(URL Encoding)
也適用於統一資源標誌符(URI)
的編碼,同樣用於 application/x-www-form-urlencoded MIME
準備資料。
一、為什麼需要URL Encoding
在URL的最初設計時,希望可以通過書面轉錄,比如寫在餐巾紙上告訴另外一人,因此URI的構成字元必須是可寫的ASCII字元。
中文不在ASCII字元中,因此中文出現在URL地址中時,需要進行編碼;同時可書寫的ASCII字元中,存在一些不安全字元
也需要轉碼,如空格
(空格容易被忽略,也容易意想不到的原因引入)。
二、編碼原理
編碼的原理
可以表述為:
將需要轉碼的字元,按指定編碼方式(預設使用UTF-8編碼)轉化為位元組流,每個位元組按16進製表示,並新增%組成一個percent編碼。
例如:漢字 “你好”
- UTF-8位元組流列印為:
-28 -67 -96 -27 -91 -67
- 對應的16進製表示為:
E4 BD A0 E5 A5 BD
- URLEncode編譯後為:
%E4%BD%A0%E5%A5%BD
2.1、哪些字元需要轉碼
上文中提到需要轉碼的字元
,那麼哪些字元是需要轉碼的字元?
這裡涉及到兩個概念:Reserved(保留字元)
和Unreserved(非保留字元)
。
Reserved(保留字元)
是那些具有特殊含義的字元,例如:"/"字元用於URL不同部分的分界符;Unreserved(非保留字元)
沒有特殊含義,包含希臘字母 / 數字 / "-" / "." / "_" / "~"
。
回到剛才的問題,哪些字元是需要轉碼的字元?
- 1、除了
Reserved(保留字元)
和Unreserved(非保留字元)
之外的所有字元,均需要percent編碼; - 2、某些情況下
Reserved(保留字元)
也需要進行percent編碼:
當Reserved(保留字元)
不用於URL分隔符,而是用於其他的位置,不代表某種特性的含義時,需要進行percent編碼。例如:保留字元用於URL請求query後面的value中時,要對此時用到的Reserved(保留字元)
做percent編碼;
2.2、注意:空格的編碼有 “+”和“%20”兩種
結論:
- 1、
空格
編碼為+
的情況:
提交表單時請求時Content-Type:application/x-www-form-urlencoded
的情況下,URL請求查詢字串中出現空格
時,需替換為+
。 - 2、其他情況
空格
編碼為%20
;
依據:
按照 rfc3986 標準,空格
在進行編碼時,編碼後對應為%20
。
但根據W3C標準:,提交表單時請求時Content-Type:application/x-www-form-urlencoded
情況下,URL請求查詢字串中出現空格
時,需替換為+
。
三、參考
rfc3986:
https://tools.ietf.org/html/rfc3986
rfc1738:
https://www.ietf.org/rfc/rfc1738.txt
W3C標準:
https://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1
維基百科:百分號編碼:
https://zh.wikipedia.org/wiki/%E7%99%BE%E5%88%86%E5%8F%B7%E7%BC%96%E7%A0%81