原来,我连一个URL都写不对…
來自我的鐵粉公號?@鬧鬧吃魚
“?閱讀本文需要 6?分鐘”
作者 l 鬧鬧?
來源 l?鬧鬧吃魚(ID:UpUp005)
又到了每周的分享時間了,今天分享一下在網絡協議中,URI的相關內容,因為在外面出差,頭圖沒法做,就用以前的老圖咯~(偷懶也這么理直氣壯)
URL是什么我想大家都知道,畢竟我們每天都接觸著,那URI是什么呢?
那我們先來看看,如果這世界上沒有URI時,會變成什么樣子呢?
沒有URI的情況下,我上傳了一些資料要分享給你們,你們要怎樣才能下載獲取呢?
首先,我得告訴你們用FTP協議訪問naonao.com,端口是8090
然后,告訴你們登陸用戶名是Naonao,密碼是Handsome
登陸成功后,你們要進入到/Naonao/Source目錄下,并且轉換為二進制模式
最后再下載如何避免過帥導致的煩惱.mp4的文件
這要不是最后的文件太吸引我,這么麻煩的步驟,我才不想去倒騰呢
可有了URI后,上面這些步驟,我們只需要在瀏覽器里直接輸入ftp://Naonao:Handsome@naonao.com:8090/Naonao/Source/如何避免過帥導致的煩惱.mp4
友情提示一下,上面的URI并不是一個完全正確的URI,因為最后面的中文沒有進行轉碼,關于轉碼解碼的問題,我們稍后再看
01
—
什么是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的超集
02
—
URI與URL的區別
雖然我們現在知道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等,通過這種方式,我們就能將我們想表達的資源進行區分
03
—
URI的組成
先上張圖,我們來看看URI由哪些部分組成
我們根據圖片上的內容來進行分析
我們先來看最重要的三點,先拿個例子,看完例子再看下面的說明
https://naonao.com?name=naonao&age=18#page-7
Scheme
Scheme指的就是方案,比如HTTP,HTTPS,FTP等,都是可以使用的,思想不要被這些常用的協議給局限了,我們還可以自定義協議,只要服務器支持即可
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-abempty、path-absolute、path-noscheme、path-rootless、path-empty
path-abempty/開頭的路徑或空路徑
path-absolute/開頭,但不能以//開頭
path-noscheme:號開頭的路徑
path-rootlesspath=noscheme,增加允許以:號開頭的路徑
path-empty
說這么多種path只是為了尊重文檔,但也別看有這么多種類型,其實使用起來是非常簡單的,綜合上述五種方案,我們可以發現,限制的都是開頭的字符
而我們只要不使用中文或者其它一些特殊字符作路徑的開頭,這樣我們的路徑都是合法的
所以路徑這東西,我們只要根據實際情況進行填寫即可
04
—
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,就算是輸入中文也能正常使用,其實是瀏覽器在背后幫我們做了轉碼解碼的苦逼活
這其實是一個非常友好的用戶體驗,不會把一些看不懂的東西直接展示給用戶,也是非常值得學習的一個理念
04
—
寫在最后
URI是網絡協議學習中必須要弄明白的一個內容,但其實總的來說并不難,只是概念性的東西稍微多了點,理解了之后,其實就是一點點內容
你可能會問,這東西學了有什么用呢?我只能回答你,學這東西沒有直接用處,但是有間接用處
比如做后臺開發的,要對接接口,給的URI若不規范,那么接口調用方就無法定位到我們的資源,最后面向Google編程老半天才解決
又或者做前端開發的,接口調用不規范,比如GET調用時query參數寫錯,那自然也調不通后臺給的接口
又比如拿到一個不熟悉的項目,通過瀏覽器的Network就可以分析到用了哪些資源,依賴了什么頁面和接口,但連URI都看不懂,那就只能問同事了,問完后還要被人一頓嫌棄
雖然遇到的這些問題都能面向Google編程或者問同事解決,但是在查資料或者咨詢的同時,浪費的時間就要靠加班來換了…加班多累啊!!!
END
如果文章對你有所幫助,請點一下右下角的“在看”,或者分享給你周圍的人~給我一點支持!
總結
以上是生活随笔為你收集整理的原来,我连一个URL都写不对…的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql docker还是rds_rd
- 下一篇: NAO机器人高尔夫中的视觉系统设计