URI Encoding

What is URL Encoding

URL Encoding 也被成為 percent encoding,URL是由有限的字符(來自US-ASCII character set)組成的,這些字符包含數(shù)字(0-9)、字幕(a-z, A-Z)、特殊字符- _ . ~

這也就意味著,URL中不能包含:

  • ASCII控制字符(退格鍵,垂直制表符,水平制表符,換行符等)
  • unsafe characters: space、\、<>、{、}
  • 不在ASCII中的字符

還有一些絕對不能出現(xiàn)在query中的字符:

  • 常見的一些對于URL有特殊意義的字符,被稱作保留字符。比如: / # ? :

那么,當你的URI中必須要包含一些不被允許的字符該怎么辦呢?

這時候就需要使用URL Encoding將不被允許的字符轉換成對應的十六進制三元字符組, 這個轉換的過程被稱為URI的encoding。

URI encode也被稱作percent-encoding, 原因是,所有不被允許的字符都需要轉義成為使用%開頭的十六進制字符組,因此也被叫做perceng encoding

哪些字符可以包含在URI中?

根據RFC 3986所述,一個valid的URI中只能包含以下84種字符:

  • 特殊字符
-._~:/?#[]@!$&'()*+,;=
  • 字母
    a-z / A-Z

  • 數(shù)字
    0-9

  • 以%開頭的十六進制三元字符組

除此之外的任何一種字符都需要是使用字符三元組替代。

如果URL中出現(xiàn)這種不被允許的字符會怎么樣呢?

  • 請求通過瀏覽器或者postman,做過轉義之后發(fā)出

如果你通過瀏覽器發(fā)出請求中包含了一些不被允許的字符,瀏覽器會幫助我們做一些轉義,別以為這是一件好事兒,因為不同的瀏覽器有不同的轉義字符的方式。這時候你可能會驚喜的發(fā)現(xiàn),同樣一個URL,chrome上請求成功,IE11直接400

  • 請求不做任何轉義直接發(fā)送到server

這種方式我也不知道如何做到,我嘗試使用curl/postman/發(fā)現(xiàn)都會被轉義,那么我們就大膽的猜測一下。

一個真的沒有轉義過包含非法字符的請求發(fā)送到server,會出現(xiàn)什么結果呢?

大膽猜測一下,server應該沒有辦法resolve這種請求,那么就有可能直接throw 400 error


簡而言之, 如果直接發(fā)送包含不允許字符的URI給server,同樣Server也不能夠識別這些字符,就有可能導致這次請求失敗

How can we achieve URL encoding in JS

JS提供了內置了兩個API對URI進行encode:

  • encodeURIComponent
  • encodeURI

他們都可以將特殊字符進行encode,那么區(qū)別是什么呢?

  • encodeURI() 不會encode: ~!@#$&*()=:/,;?+'

說明這個function可以作用于整個URI

encodeURI('https://stackoverflow.com/questions/?path={"a":"1"}')

// "https://stackoverflow.com/questions/?path=%7B%22a%22:%221%22%7D"
  • encodeURIComponent() will not encode: ~!*()'

說明類似于?這種分界query和path的符號也會被轉義,因此無法作用于整個URI

encodeURIComponent是對URI的組成部分進行編碼的方法,而不用對整個URL進行編碼。

encodeURIComponent('https://stackoverflow.com/questions/?path={"a":"1"}')

// "https%3A%2F%2Fstackoverflow.com%2F%3Fpath%3D%7B%22a%22%3A%221%22%7D"

這樣的URL根本無法被識別

Note

請不要使用escape,此方法已經被廢棄

實例

  • 在client端發(fā)一個請求獲取所有的search result, 我在code中直接使用了fetch給下面的url發(fā)送了請求
https://xxxx/AAA/api/results?info={
"name":"yoyo"}&options={"page":1,"pageSize":30}
  • 當我在chrome中打開頁面的時候,server端接收到的請求是:
https://xxxx/AAA/api/results?info={%22name%22:%22yoyo%22}&options={%22page%22:1,%22pageSize%22:30}
  • 當我在IE11中打開頁面的時候,發(fā)現(xiàn)這個請求總是400,結果查看server端接收到的請求是:
https://xxxx/AAA/api/results?info={\x22name\x22:\x22yoyo\x22}&options={\x22page\x22:1,\x22pageSize\x22:30}

由于window的編碼方式不同,導致server端無法識別\x22,所以直接返回400

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • https://nodejs.org/api/documentation.html 工具模塊 Assert 測試 ...
    KeKeMars閱讀 6,607評論 0 6
  • API定義規(guī)范 本規(guī)范設計基于如下使用場景: 請求頻率不是非常高:如果產品的使用周期內請求頻率非常高,建議使用雙通...
    有涯逐無涯閱讀 2,927評論 0 6
  • 最近難得有時間,可以看看平時經常用的牛逼的三方框架是怎么實現(xiàn)的,學習學習。比如okhttp ,眼下安卓開發(fā) 網絡框...
    張哲1111閱讀 1,318評論 0 1
  • 8. 方法定義(Method Definitions) 通用的HTTP/1.0的方法集將在下面定義,雖然該方法集可...
    Palomar閱讀 3,425評論 0 2
  • 不知不覺,大半生已過。這一路走來,經歷了坎坷,也收獲了快樂。不管怎么說,生活總是喜憂參半的,放大自己的格局...
    晴空一鶴范祖華閱讀 509評論 0 11

友情鏈接更多精彩內容