今天,完全弄懂什麼是URI

又到了每週二的分享時間了,今天分享一下在網絡協議中,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解決了什麼問題,我想各位內心確定是有數了

不過在瞭解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的區別

雖然咱們如今知道URI是URL的超集,但在網絡中,URL與URI這哥倆長的實在太像了,不少時候咱們傻傻分不清URL與URI到底誰是誰

咱們先來看看定義的區別,URI與URL不一樣的部分就是IdentifierLocator,URI注重的是惟一標識符,而URL注重的是位置

打個簡單的比喻,若是用URI來表述咱們本身,那麼URI就是咱們的身份證號碼,URL就是咱們身份證上的家庭住址,經過身份證號(URI)確定能找到我,可是你經過個人住址(URL)那就不必定能找到我了哦

再來講說資源包含了什麼

資源這倆字,包含的東西就太廣了,既能夠是圖片、文檔,也能夠是今天的天氣

也能夠是不能經過互聯網訪問的實體,例如人、公司

也能夠是某種抽象概念,例如親屬關係或者你是否是渣男

可是要注意一點,URI並非與資源一一對應的,一個資源是能夠擁有不少個URI,但一個URI只會對應一個資源,就像咱們手上有不少張銀行卡,但每一個銀行卡對應的開戶人,也只有咱們本身一我的

Identifier的實際用處就是將當前資源與其它資源區分開來的名稱

經過IdentifierSource的含義,咱們就能夠很明顯的感受到URI的一個目標,它更傾向於資源提供者把本身把所擁有的資源與其它資源區分開

好比不能經過互聯網訪問的實體,好比人,咱們就能夠經過URL去定義Mine,Father,Relationship等,經過這種方式,咱們就能將咱們想表達的資源進行區分

URI的組成

先上張圖,咱們來看看URI由哪些部分組成

咱們根據圖片上的內容來進行分析

咱們先來看最重要的三點,先拿個例子,看完例子再看下面的說明

https://naonao.com?name=naonao&age=18#page-7

Scheme

Scheme指的就是方案,好比HTTPHTTPSFTP等,都是可使用的,思想不要被這些經常使用的協議給侷限了,咱們還能夠自定義協議,只要服務器支持便可

Scheme能夠是由字母數字+-.,都是容許的

注意:在Scheme以後,必須使用://把Scheme與後面的部分區分開來

Query

query就是查詢參數,是一個可選的參數,若有有的話,那麼必需要以?開頭

咱們最經常使用的形式就是使用key=value,好比上面的例子name=naonao

但Query並不只僅是支持這種,它是能夠支持pchar,/,?等形式

?的話你們都知道,要使用Query查詢參數,那麼就必須在前面加上?,而pchar是什麼呢?這點咱們想了解的話,須要去參考RFC中的詳細描述,這不是今天內容的重點

fragment

fragment也是可選的,若是有的話,必須以#開頭

好比上面的示例,page-7指向的是一個段落

它所支持的格式跟Query所支持的格式一致

authority

authority包含了用戶名與密碼(user infomation),還有主機名(host),以及端口號(port)

像用戶名密碼這東西,咱們如今基本已經不使用這種方式了,由於在URI中明文傳輸帳號密碼,實在不安全

如今還在用的,基本上也就是常用ftp下載資源時咱們才使用

因此咱們一般只使用host:port,即主機名+端口號的形式

主機名是不可省略的,由於一但省略,咱們就找不到對應的服務器

而端口號咱們卻能夠省略,好比HTTP的默認端口號就是80端口,HTTPS的默認端口號就是443端口

path

主機名後面緊跟的就是咱們的path

在URI中,path部分必需要以/開頭,因此不要把path以前的/誤覺得是前面authority的結尾

path也分了不少種,分別是path-abemptypath-absolutepath-noschemepath-rootlesspath-empty

  • path-abempty 以/開頭的路徑或空路徑
  • path-absolute 以/開頭,但不能以//開頭
  • path-noscheme 以非:號開頭的路徑
  • path-rootless 相對path=noscheme,增長容許以:號開頭的路徑
  • path-empty 空路徑

說這麼多種path只是爲了尊重文檔,但也別看有這麼多種類型,其實使用起來是很是簡單的,綜合上述五種方案,咱們能夠發現,限制的都是開頭的字符

而咱們只要不使用中文或者其它一些特殊字符做路徑的開頭,這樣咱們的路徑都是合法的

因此路徑這東西,咱們只要根據實際狀況進行填寫便可

URI的編碼

終於到了填坑時間

最開始咱們舉例說若是世上沒有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編程或者問同事解決,可是在查資料或者諮詢的同時,浪費的是咱們的時間以及同事的時間

相關文章
相關標籤/搜索