一般我們日常在上網的時候,會在瀏覽器的位址列裡輸入一個網站的 "網址",點選下回車,就會跳到你想去的網站,就類似這樣
但其實,叫做 "網址" 並不是特別的準確,確切的說,應該叫做 URL
到底啥是URL
那到底啥是 URL 呢? 不就是一個網址嗎?
URL 是英文 Uniform Resource Locator 的縮寫,即統一資源定位器,是因特網上用於指定資訊位置的表示方法,通過它就能找到網上的某個你要的資源
URL的組成
雖然我們平時使用瀏覽器的時候,只要輸入baidu.com
或者qq.com
就能正常上網了,但其實我們輸入的只是整個URL中的一小部分
來,我先看看一個相對完整的URL的整體結構是怎麼樣的
這裡大致分了幾個部分,我們一個個來看,它們具體是幹什麼的
協議
圖中http://
這部分就是協議部分,即指定了URL是以什麼協議傳送網路請求的
常見的協議如:http://
、https://
、ftp://
、file://
,比如: http://
就是超文字傳輸協議,平時上網大多用這個協議,https://
是以安全為目標的HTTP協議。
地址
圖中localhost
就是地址部分,用來確定URL所要訪問的伺服器的網路地址(也就是網址)。在URL中,地址可以用三個形式來表示:域名
、主機名
、IP地址
域名
我們平時輸入的www.baidu.com
、www.qq.com
就是域名,域名也分一級域名
、二級域名
、以及頂級域名
。
-
頂級域名:在域名的尾巴部分,
.com
這種就是頂級域名
,頂級域名一般都代表網站屬於某種機構或組織。像.com
(商業機構)、.org
(非盈利組織)、
.gov
(政府機構)這類就是常見的頂級域名,除此之外,還有些代表國家的頂級域名,如:.cn
(中國)、.us
(美國)、.jp
(日本)等等 -
一級域名:像
qq.com
就是一級域名
,看上去十分簡潔,在頂級域名.com
前只有一個單詞短語 -
二級域名:而
mail.qq.com
和v.qq.com
這種前面加了mail.
、v.
等字串的就叫二級域名
不過,域名也只是一串文字,計算機和路由器並不能直接認出它,還需要通過DNS
伺服器找到域名對應的IP地址
,再通過底層的TCP/IP
協議路由到對應的機器上去 (這些內容不是本文的重點暫時略過,先挖個坑再說)
主機名
主機名就是某臺計算機的名字,在一個區域網內,可以通過主機名
找到你要訪問的計算機。主機名和域名一樣,計算機和路由器不認它,需要通過HOSTS檔案
這樣的技術找到主機名
和IP地址
的關聯關係,最後還是翻譯成IP地址
再繼續傳送網路請求
圖中的localhost
也是主機名
,但是一種比較特殊的主機名
,是給 迴環地址的一個標準主機名,就是代表本機自己的地址。
IP地址
在URL中也可以直接用IP地址
來代替域名或主機名,如192.168.0.1
,關於IP地址
的相關知識點放到以後再講(繼續挖坑)
埠號
圖中在冒號:
後面的那串數字8080
就是埠號,一臺伺服器上可以開多個埠號,往往一個網路服務程式就對應一個埠號
比如,我在機器 A 上,開了兩個服務程式,分別是 Tomcat
和SSH
,讓它們分別關聯埠8080
和22
,那URL中如果埠號是8080
就是會訪問到Tomcat
程式,22
就會連線SSH服務。
但可能有小夥伴會有疑問:誒,我平時上百度看到的URL是http://www.baidu.com
沒看到有埠號啊
其實是有的,埠號是80
,只是它被隱藏起來了,我們看不到而已,而這個80
埠也就是URL的預設埠號
但不是所有URL的預設埠號都是80
,如果協議是http://
,預設埠號為80
,但若是https://
協議,預設埠號就是443
了
虛擬目錄
從第一個斜槓/
開始,到最後一個斜槓/
結束的那部分,也就是圖中/app/user/
那部分即為虛擬目錄
它就類似我們電腦中檔案目錄的格式,第一個/
為根目錄,每多一個/
就多進入一層目錄
檔名
從域名後開始算起的最後一個斜槓/
開始,到?
為止,沒有?
則到#
為止,或者?
和#
都沒有就是到整個URL結束為止的那部分就為檔名
說起來很繞吧,其實就是圖中 info.do
這部分,它一般包含檔名和副檔名('.'後面那部分),用來指代一個URL所訪問的具體檔案或資源,它可以是圖片、html檔案、css檔案,也可以是js檔案、字型檔案等等,它也可以不是某種檔案,而是服務端後臺執行的某段程式。
甚至可以省略不寫虛擬目錄和檔名,因為它們本來就不是必須的,就如http://www.baidu.com
這樣的URL就沒有檔名,但伺服器會在預設的情況下給你定位到某個特定的檔案或程式上去。
查詢引數
從?
後到#
結束,即圖中的?uid=101&ty=2
為查詢引數
查詢引數,也稱為URL引數、查詢字串,英文名為 Query
,它是用來向服務端以字串的形式傳遞引數和少數資料用的
其引數形式一般都以多個鍵值對
的形式進行表示,如 a=1
、b=2
就是兩個鍵值對
,鍵為"a"和"b",值為對應的"1"和"2", 多個鍵值對
用&
連起來:a=1&b=2
URL編碼
但引數要傳遞的某些值往往帶有特殊字元,這些字元和URL標準的格式衝突,比如要傳a&b
這樣字串,和查詢引數鍵值對的連線符&
衝突了,若不加以區分就會產生歧義
而最簡單的辦法,就是對引數值進行編碼,稱為 URL Encoding,通過編碼,a&b
變成了a%26b
,就不再包含會衝突的特殊字元
而有些引數即便有特殊字元,也不會被編碼,除非自行強制編碼,比如URL中引數值是另外一串URL,就可以寫成 http://localhost/do?url=http://www.baidu.com
這種特殊情況不會有歧義,因為計算機系統認得出引數是另一串URL,就會按URL的形式來解析,但當子URL又包含子引數和多子鍵值對的時候也難免會分不清引數到底是兒子的還是父親的,這時還是強制編碼的好
列表引數
URL的引數是一個個鍵值對,即一個key
對應一個value
,那如果是一個key
要傳遞多個值,也就是一個列表咋辦?也好辦
URL的引數名是可以重複的,比如a=1&a=2&a=3
,這裡穿了3個引數名都為a
的查詢引數,是完全可以的,可以利用這種特性,按順序將 1
、2
、3
作為引數a
的列表值
為了表示更清楚點,一般都會在列表引數名後面加上一對方括號[]
,如:a[]=1&a[]=2&a[]=3
但是,對於URL引數的寫法和格式的標準,也沒有特別嚴格的規定,以上幾種形式一般都會支援
錨
圖中#
後面那部分字串,#abc
就是錨部分
錨,英文稱做Reference
,通常也是用來傳遞引數等資訊,但與查詢引數的本質區別就是這部分內容不會被傳遞到伺服器端
錨一般用於頁面,比如在瀏覽網頁的時候,按個按鈕突然幫你定位到頁首或頁面中的某個位子去了,這就是錨
現在隨著前後端分離技術,尤其是 vue
、reactjs
等前端框架的興起,錨作為前端javascript
程式處理的引數載體也越來越重要了
結語
URL看似已經習以為常、非常簡單的東西,背後往往也隱藏著很多技術細節和知識點,甚至這短短一篇文章也沒辦法窮盡
其實URL的內容還有不少,比如<使用者名稱>@<密碼>
這種使用者驗證資訊在URL中的傳遞,由於篇幅的關係還沒有講到
所以我講分幾篇文章來講解HTTP
協議的其中幾個重要部分,如果這一系列文章對你有幫助,別忘了關注哦~
最後,我還要推薦一款十分好用的 Java 端 HTTP
框架: Forest
官網:http://forest.dtflyx.com
Gitee倉庫:https://gitee.com/dt_flys/forest
Github倉庫:https://github.com/dromara/forest
這是一款聲名式的HTTP框架,簡單好用,因為它將拼接URL、請求頭、請求體引數、等待響應,失敗重試,轉換響應資料到 Java 型別等髒活累活全包了