HTTP基礎系列之:一文搞懂URL

一般我們日常在上網的時候,會在瀏覽器的地址欄里輸入一個網站的 “網址”,點擊下回車,就會跳到你想去的網站,就類似這樣

5McfPA.png

但其實,叫做 “網址” 並不是特別的準確,確切的說,應該叫做 URL

到底啥是URL

那到底啥是 URL 呢? 不就是一個網址嗎?

URL 是英文 Uniform Resource Locator 的縮寫,即統一資源定位器,是網際網路上用於指定資訊位置的表示方法,通過它就能找到網上的某個你要的資源

URL的組成

雖然我們平時使用瀏覽器的時候,只要輸入baidu.com或者qq.com就能正常上網了,但其實我們輸入的只是整個URL中的一小部分

來,我先看看一個相對完整的URL的整體結構是怎麼樣的

5MoSMj.png

這裡大致分了幾個部分,我們一個個來看,它們具體是幹什麼的

協議

圖中//這部分就是協議部分,即指定了URL是以什麼協議發送網路請求的

常見的協議如:////ftp://file://,比如: //就是超文本傳輸協議,平時上網大多用這個協議,//是以安全為目標的HTTP協議。

地址

圖中localhost就是地址部分,用來確定URL所要訪問的伺服器的網路地址(也就是網址)。在URL中,地址可以用三個形式來表示:域名主機名IP地址

域名

我們平時輸入的www.baidu.comwww.qq.com就是域名,域名也分一級域名二級域名、以及頂級域名

  • 頂級域名:在域名的尾巴部分,.com這種就是頂級域名,頂級域名一般都代表網站屬於某種機構或組織。像.com(商業機構)、.org(非盈利組織)、
    .gov(政府機構)這類就是常見的頂級域名,除此之外,還有些代表國家的頂級域名,如:.cn(中國)、.us(美國)、.jp(日本)等等

  • 一級域名:像qq.com就是一級域名,看上去十分簡潔,在頂級域名.com前只有一個單詞短語

  • 二級域名:而mail.qq.comv.qq.com這種前面加了mail.v.等字元串的就叫二級域名

不過,域名也只是一串文字,電腦和路由器並不能直接認出它,還需要通過DNS伺服器找到域名對應的IP地址,再通過底層的TCP/IP協議路由到對應的機器上去 (這些內容不是本文的重點暫時略過,先挖個坑再說)

主機名

主機名就是某台電腦的名字,在一個區域網內,可以通過主機名找到你要訪問的電腦。主機名和域名一樣,電腦和路由器不認它,需要通過HOSTS文件這樣的技術找到主機名IP地址的關聯關係,最後還是翻譯成IP地址再繼續發送網路請求

圖中的localhost也是主機名,但是一種比較特殊的主機名,是給 迴環地址的一個標準主機名,就是代表本機自己的地址。

IP地址

在URL中也可以直接用IP地址來代替域名或主機名,如192.168.0.1,關於IP地址的相關知識點放到以後再講(繼續挖坑)

埠號

圖中在冒號:後面的那串數字8080就是埠號,一台伺服器上可以開多個埠號,往往一個網路服務程式就對應一個埠號

比如,我在機器 A 上,開了兩個服務程式,分別是 TomcatSSH,讓它們分別關聯埠808022,那URL中如果埠號是8080就是會訪問到Tomcat程式,22就會連接SSH服務。

但可能有小夥伴會有疑問:誒,我平時上百度看到的URL是//www.baidu.com沒看到有埠號啊

其實是有的,埠號是80,只是它被隱藏起來了,我們看不到而已,而這個80埠也就是URL的默認埠號

但不是所有URL的默認埠號都是80,如果協議是//,默認埠號為80,但若是//協議,默認埠號就是443

虛擬目錄

從第一個斜杠/開始,到最後一個斜杠/結束的那部分,也就是圖中/app/user/那部分即為虛擬目錄

它就類似我們電腦中文件目錄的格式,第一個/為根目錄,每多一個/就多進入一層目錄

文件名

從域名後開始算起的最後一個斜杠/開始,到?為止,沒有?則到#為止,或者?#都沒有就是到整個URL結束為止的那部分就為文件名

說起來很繞吧,其實就是圖中 info.do 這部分,它一般包含文件名和擴展名(‘.’後面那部分),用來指代一個URL所訪問的具體文件或資源,它可以是圖片、html文件、css文件,也可以是js文件、字體文件等等,它也可以不是某種文件,而是服務端後台執行的某段程式。

甚至可以省略不寫虛擬目錄和文件名,因為它們本來就不是必須的,就如//www.baidu.com這樣的URL就沒有文件名,但伺服器會在預設的情況下給你定位到某個特定的文件或程式上去。

查詢參數

?後到#結束,即圖中的?uid=101&ty=2為查詢參數

查詢參數,也稱為URL參數、查詢字元串,英文名為 Query,它是用來向服務端以字元串的形式傳遞參數和少數數據用的

其參數形式一般都以多個鍵值對的形式進行表示,如 a=1b=2就是兩個鍵值對,鍵為”a”和”b”,值為對應的”1″和”2″, 多個鍵值對&連起來:a=1&b=2

URL編碼

但參數要傳遞的某些值往往帶有特殊字元,這些字元和URL標準的格式衝突,比如要傳a&b這樣字元串,和查詢參數鍵值對的連接符&衝突了,若不加以區分就會產生歧義

而最簡單的辦法,就是對參數值進行編碼,稱為 URL Encoding,通過編碼,a&b變成了a%26b,就不再包含會衝突的特殊字元

而有些參數即便有特殊字元,也不會被編碼,除非自行強制編碼,比如URL中參數值是另外一串URL,就可以寫成 //localhost/do?url=//www.baidu.com
這種特殊情況不會有歧義,因為電腦系統認得出參數是另一串URL,就會按URL的形式來解析,但當子URL又包含子參數和多子鍵值對的時候也難免會分不清參數到底是兒子的還是父親的,這時還是強制編碼的好

列表參數

URL的參數是一個個鍵值對,即一個key對應一個value,那如果是一個key要傳遞多個值,也就是一個列表咋辦?也好辦

URL的參數名是可以重複的,比如a=1&a=2&a=3,這裡穿了3個參數名都為a的查詢參數,是完全可以的,可以利用這種特性,按順序將 123作為參數a的列表值

為了表示更清楚點,一般都會在列表參數名後面加上一對方括弧[],如:a[]=1&a[]=2&a[]=3

但是,對於URL參數的寫法和格式的標準,也沒有特別嚴格的規定,以上幾種形式一般都會支援

圖中#後面那部分字元串,#abc就是錨部分

錨,英文稱做Reference,通常也是用來傳遞參數等資訊,但與查詢參數的本質區別就是這部分內容不會被傳遞到伺服器端

錨一般用於頁面,比如在瀏覽網頁的時候,按個按鈕突然幫你定位到頁首或頁面中的某個位子去了,這就是錨

現在隨著前後端分離技術,尤其是 vuereactjs 等前端框架的興起,錨作為前端javascript程式處理的參數載體也越來越重要了

結語

URL看似已經習以為常、非常簡單的東西,背後往往也隱藏著很多技術細節和知識點,甚至這短短一篇文章也沒辦法窮盡

其實URL的內容還有不少,比如<用戶名>@<密碼>這種用戶驗證資訊在URL中的傳遞,由於篇幅的關係還沒有講到

所以我講分幾篇文章來講解HTTP協議的其中幾個重要部分,如果這一系列文章對你有幫助,別忘了關注哦~

最後,我還要推薦一款十分好用的 Java 端 HTTP 框架: Forest

官網://forest.dtflyx.com
Gitee倉庫://gitee.com/dt_flys/forest
Github倉庫://github.com/dromara/forest

這是一款聲名式的HTTP框架,簡單好用,因為它將拼接URL、請求頭、請求體參數、等待響應,失敗重試,轉換響應數據到 Java 類型等臟活累活全包了