又到了每週二的分享時間了,今天分享一下在網絡協議中,URI的相關內容,由於在外面出差,頭圖無法作,就用之前的老圖咯~(偷懶也這麼義正詞嚴)前端
URL是什麼我想你們都知道,畢竟咱們天天都接觸着,那URI是什麼呢?編程
那咱們先來看看,若是這世界上沒有URI時,會變成什麼樣子呢?瀏覽器
沒有URI的狀況下,我上傳了一些資料要分享給大家,大家要怎樣才能下載獲取呢?安全
首先,我得告訴大家用FTP
協議訪問naonao.com
,端口是8090
服務器
而後,告訴大家登錄用戶名是Naonao
,密碼是Handsome
網絡
登錄成功後,大家要進入到/Naonao/Source
目錄下,而且轉換爲二進制模式less
最後再下載如何避免過帥致使的煩惱.mp4
的文件學習
這要不是最後的文件太吸引我,這麼麻煩的步驟,我纔不想去倒騰呢編碼
可有了URI後,上面這些步驟,咱們只須要在瀏覽器裏直接輸入ftp://Naonao:Handsome@naonao.com:8090/Naonao/Source/如何避免過帥致使的煩惱.mp4
這樣就能夠直接下載網絡上的資源了code
友情提示一下,上面的URI並非一個徹底正確的URI,由於最後面的中文沒有進行轉碼,關於轉碼解碼的問題,咱們稍後再看
看完上面的內容,URI解決了什麼問題,我想各位內心確定是有數了
不過在瞭解URI以前,咱們須要先簡單瞭解下URL與URN
URL在RFC1738(1994.12)中的定義是Uniform Resource Locator
,表示資源的所在位置,指望提供查找資源的方法
而URN在RFC2141(1997.5)中的定義是Uniform Resource Name
,指望爲資源提供持久的,位置無關的標識方式,並容許簡單的將多個命名空間映射到單個URN命名空間
直接說URN這種概念,有些人可能不大清楚是個什麼東西,我說個例子,男生確定清楚,好比磁力連接~嘻嘻,有沒有回想起什麼不可言論的東西?
我在網上找了個葫蘆娃的磁力下載地址,各位圍觀一下,有沒有以爲這東西很眼熟呢?
magnet:?xt=urn:btih:bdab9b6759950fab3c8cbde2669bea6195491034
好咯,不熟悉也沒事,這也不是今天的重點,咱們知道這玩意大概長城這樣就行了。咱們如今來看看,URI的定義是什麼
URI的全名呢就是Uniform Resource Identifier
,主要用於區分資源,它包含了URL與URN的概念,主要是用於取代URL和URN的概念~
換句話說,URI能夠是URL/URN,但URL/URN不必定就是URI,也就是說URI是URL/URN的超集
雖然咱們如今知道URI是URL的超集,但在網絡中,URL與URI這哥倆長的實在太像了,不少時候咱們傻傻分不清URL與URI到底誰是誰
咱們先來看看定義的區別,URI與URL不一樣的部分就是Identifier
與Locator
,URI注重的是惟一標識符,而URL注重的是位置
打個簡單的比喻,若是用URI來表述咱們本身,那麼URI就是咱們的身份證號碼,URL就是咱們身份證上的家庭住址,經過身份證號(URI)確定能找到我,可是你經過個人住址(URL)那就不必定能找到我了哦
再來講說資源包含了什麼
資源這倆字,包含的東西就太廣了,既能夠是圖片、文檔,也能夠是今天的天氣
也能夠是不能經過互聯網訪問的實體,例如人、公司
也能夠是某種抽象概念,例如親屬關係或者你是否是渣男
可是要注意一點,URI並非與資源一一對應的,一個資源是能夠擁有不少個URI,但一個URI只會對應一個資源,就像咱們手上有不少張銀行卡,但每一個銀行卡對應的開戶人,也只有咱們本身一我的
Identifier
的實際用處就是將當前資源與其它資源區分開來的名稱
經過Identifier
與Source
的含義,咱們就能夠很明顯的感受到URI的一個目標,它更傾向於資源提供者把本身把所擁有的資源與其它資源區分開
好比不能經過互聯網訪問的實體,好比人,咱們就能夠經過URL去定義Mine,Father,Relationship等,經過這種方式,咱們就能將咱們想表達的資源進行區分
先上張圖,咱們來看看URI由哪些部分組成
咱們根據圖片上的內容來進行分析
咱們先來看最重要的三點,先拿個例子,看完例子再看下面的說明
https://naonao.com?name=naonao&age=18#page-7
Scheme
指的就是方案,好比HTTP
,HTTPS
,FTP
等,都是可使用的,思想不要被這些經常使用的協議給侷限了,咱們還能夠自定義協議,只要服務器支持便可
Scheme
能夠是由字母
,數字
,+
,-
,.
,都是容許的
注意:在Scheme
以後,必須使用://
把Scheme與後面的部分區分開來
query就是查詢參數,是一個可選的參數,若有有的話,那麼必需要以?
開頭
咱們最經常使用的形式就是使用key=value
,好比上面的例子name=naonao
但Query並不只僅是支持這種,它是能夠支持pchar
,/
,?
等形式
?
的話你們都知道,要使用Query查詢參數,那麼就必須在前面加上?
,而pchar
是什麼呢?這點咱們想了解的話,須要去參考RFC中的詳細描述,這不是今天內容的重點
fragment也是可選的,若是有的話,必須以#
開頭
好比上面的示例,page-7
指向的是一個段落
它所支持的格式跟Query
所支持的格式一致
authority包含了用戶名與密碼(user infomation),還有主機名(host),以及端口號(port)
像用戶名密碼這東西,咱們如今基本已經不使用這種方式了,由於在URI中明文傳輸帳號密碼,實在不安全
如今還在用的,基本上也就是常用ftp
下載資源時咱們才使用
因此咱們一般只使用host:port
,即主機名+端口號的形式
主機名是不可省略的,由於一但省略,咱們就找不到對應的服務器
而端口號咱們卻能夠省略,好比HTTP
的默認端口號就是80端口,HTTPS
的默認端口號就是443端口
主機名後面緊跟的就是咱們的path
在URI中,path
部分必需要以/
開頭,因此不要把path
以前的/
誤覺得是前面authority
的結尾
path
也分了不少種,分別是path-abempty
、path-absolute
、path-noscheme
、path-rootless
、path-empty
/
開頭的路徑或空路徑/
開頭,但不能以//
開頭:
號開頭的路徑path=noscheme
,增長容許以:
號開頭的路徑說這麼多種path
只是爲了尊重文檔,但也別看有這麼多種類型,其實使用起來是很是簡單的,綜合上述五種方案,咱們能夠發現,限制的都是開頭的字符
而咱們只要不使用中文或者其它一些特殊字符做路徑的開頭,這樣咱們的路徑都是合法的
因此路徑這東西,咱們只要根據實際狀況進行填寫便可
終於到了填坑時間
最開始咱們舉例說若是世上沒有URI時該如何下載資源,我給出的例子URI裏面帶了中文,其實在URI裏只能使用ASCII碼
但若是咱們的URI裏出現了除ASCII碼
之外的內容,或者是出現了URI中的用於標識的字符好比?``#``/``&
等,那麼就會引發URI解析錯誤,那這時候該怎麼辦呢?
爲了不這種狀況出現,URI引入了編碼機制
規則很是的簡單粗暴,在ASCII碼
表內的特殊字符,直接就轉換成ASCII碼
了
對於ASCII碼
之外的內容,就轉換成十六進制的字節,而後在前面加上一個%
,例如空格就被轉義成%20
,?
被轉譯成%3F
像中文這種,十六進制字節值表示不全,須要UTF-8編碼才能表述完整的,就是轉成十六進制(UTF-8)的格式,例如鬧鬧
就會被轉義成%e9%97%b9%e9%97%b9
由於鬧
對應的十六進制UTF-8的編碼就是E9 97 B9
,而後每一個字節碼前面加上%
,就能夠獲得上述結果了
平時咱們在瀏覽器中的地址欄中輸入的URI,就算是輸入中文也能正常使用,實際上是瀏覽器在背後幫咱們作了轉碼解碼的苦逼活
這實際上是一個很是友好的用戶體驗,不會把一些看不懂的東西直接展現給用戶,也是很是值得學習的一個理念
URI是網絡協議學習中必需要弄明白的一個內容,但其實總的來講並不難,只是概念性的東西稍微多了點,理解了以後,其實就是一點點內容
你可能會問,這東西學了有什麼用呢?我只能回答你,學這東西沒有直接用處,可是有間接用處
好比作後臺開發的,要對接接口,給的URI若不規範,那麼接口調用方就沒法定位到咱們的資源,最後面向Google編程老半天才解決
又或者作前端開發的,接口調用不規範,好比GET調用時query參數寫錯,那天然也調不通後臺給的接口
又好比拿到一個不熟悉的項目,經過瀏覽器的Network就能夠分析到用了哪些資源,依賴了什麼頁面和接口,但連URI都看不懂,那就只能問同事了,問完後還要被人一頓嫌棄
雖然遇到的這些問題都能面向Google編程或者問同事解決,可是在查資料或者諮詢的同時,浪費的是咱們的時間以及同事的時間