urlencode和rawurlencode,傻傻分不清
最近半年我寫了很多Web方面的文章,看上去很簡單,但如果深究下去,則不是那麼一回事了,今天聊聊url編碼的事情。
很多人對urlencode編碼很熟悉,但對rawurlencode卻瞭解不多,其實對於URL編碼,rawurlencode才是標準,它定義在 RFC3986 上,這個 RFC 描述瞭如何定義一個 URL,URL 其實本質上不是 HTTP 協議的一部分,只是 URL 和 HTTP 協議結合的比較緊密,所以總覺得 HTTP 協議包含 URL。
先描述下rawurlencode,它也叫做百分號編碼(Percent-encoding),首先思考一個問題,為什麼URL需要編碼,原因就在於早期的 URL 只有 ASCII 字元,所以無需編碼。
但世界上有多種語言,為了讓 URL 符合語義標準,必須轉碼,主要有以下幾種字元需要編碼:
-
ASCII 控制字元。
-
Non-ASCII,比如中文字元。
-
保留字元,比如/符號有特殊含義,為了輸出原始/符號,必須編碼。
-
不安全字元,這些字元(比如<、\、%)應該可以稱為“應用字元”,對應的就是 HTML 中的“實體字元”。
那麼具體如何編碼呢?
-
非字母和數字字元替換為%符號,後面跟著字元的十六進位制。
-
破折號、下劃線、點號和波浪號無需編碼。
-
空格替換為%20。
接著說說urlencode,它基於rawurlencode標準,但有略微的不同,它定義在rfc1866,這個rfc屬於html標準的一部分,編碼方式和 application/x-www-form-urlencoded MIME 編碼方式一致。
urlencode處理 query string 的編碼,而 rawurlencode 被認為處理 url 編碼,這可以看做一個區別。
urlencode 和 rawurlencode 在編碼方式上有二處區別:
-
波浪號需要百分號編碼。
-
空格替換為+。
那麼為什麼不能保持一致呢?可能是歷史原因,但 rfc2396 認為 url 中的 + 符號是一個保留字元,所以 rawurlencode 編碼方式更標準。
在具體寫程式碼的時候,其實很少接觸到 urlencode 編碼,因為瀏覽器,web伺服器,程式碼框架都做了封裝,比如 web 伺服器會自動urlencode, curl 庫也會自動urlencode query string。
那為什麼今天提到 rawurlencode 呢,我在使用阿里雲和騰訊雲API的時候,在對API簽名的時候,會對各個 query string 進行 rawurlencode,然後再計算前面,至於為什麼不直接使用 urlencode,是我非常好奇的。
類似文章: