”加和不加到底有什麼區別?

URL 是我們每天暢遊在互聯網世界中最最常見的東西了,對於普通用戶來說,URL 就是一個字符串,比如 http://www.baidu.com ,但是對於我們開發者而言,除了 URL,還有一個東西叫做 URI,很多人經常搞不清楚這兩個概念,本文我們就從這個話題開始。

從 URN 開始

在介紹這兩個東西之前,我們還得先說說另外一個東西,叫做URN,URN的全程為Uniform Resource 譯作統一資源名稱,URN、URL與URI的關係類似於下圖:

請求地址最後面的“/”加和不加到底有什麼區別?

由上圖可以看到,URN 和 URL 實際上是 URI 範疇之內的概念。URN 表示給每一個互聯網資源取一個名字,但是互聯網資源千千萬萬,給每一個資源取一個不重複的名字顯然不太現實,因此,並不是所有的互聯網資源都有 URN ,URN 就類似於一個人的身份證號碼,是唯一的,但是通過這個身份證號碼找不到這個人,要找到這個人我們得通過類似於下面這種地址 “中國/廣東省/廣州市/天河區/馬場路/南國花園/8棟/1203室” ,這種能夠查找到某一個資源的字符串就是 URL ,URL 全稱叫做 Uniform Resource Locator ,譯作統一資源定位符,表示一個資源的地點。

URL 與 URI

URI 是 Uniform Resource Identifier 的縮寫,譯作統一資源標識符,RFC2396 中對這三個單詞做了如下定義:

Uniform

規定統一的格式可方便處理多種不同類型的資源,而不用根據上下文環境來識別資源指定的訪問方式。另外,加入新增的協議方案(如 http: 或 ftp:)也更容易。

Resource

資源的定義是“可標識的任何東西”。除了文檔文件、圖像或服務(例如當天的天氣預報)等能夠區別於其他類型的,全都可作為資源。另外,資源不僅可以是單一的,也可以是多數的集合體。

Identifier

表示可標識的對象。也稱為標識符。

由此可見,URI 就是由某個協議方案表示的資源的定位標識符,而協議方案就是訪問資源時所採用的協議類型的名稱,比如我們採用 HTTP 協議時,協議方案就是 HTTP ,我們採用 FTP 協議時,協議方案就是 FTP ,另外還有 file、mailto、telnet 等。

按照 RFC3986 的說法,一個 URI 可以被進一步歸類為一個定位器(URL),一個名字(URN),或兩者都是。也就是說 URI 可以是 URL ,也可以是 URN 或兩者兼備,如果你關心資源的名稱,那就將 URI 定義成 URN 的形式,如果你關心資源的位置,那麼就將 URI 定義成 URL 的形式,URI 中包括了 URN 和 URL 。在 RFC3986 文檔中還有如下一句話:

“Future specifications and related documentation should use the general term “URI” rather than the more restrictive terms “URL” and “URN””

這句話告訴我們未來應該使用更加通用的 URI 術語,而不是受限制頗多的 URL 和 URN 。

前面介紹了 URI ,接下來我們再來探討下 URI 的格式(基於前文得出的結論,下面涉及到的地址我將都以 URI 來稱呼)。

URI 的格式

對於普通用戶,說 URI 他們可能有點懵,但是說 http 開頭的那個字符串肯定都知道是什麼了,我們常見的網址除了 http: 開頭之外,也有 ftp: 開頭的,也有 mailto: 開頭的,分別代表不同的含義,這是因為瀏覽器的功能不僅僅侷限於訪問 web 服務器,也可以用來訪問 ftp 服務器,也可以用來瀏覽本地文件,也可以用來發送郵件,因此瀏覽器需要有一個東西來判斷使用哪種功能來訪問相應的數據,因此有了協議,也有了各種各樣不同的 URI 。如下圖是一個完整的URI:

請求地址最後面的“/”加和不加到底有什麼區別?

這其中用戶名、密碼和端口號都可以省略,在瀏覽器拿到這樣一個 URI 之後,首先會對其進行解析,比如上面這個地址,瀏覽器經過解析之後,知道要去獲取 www.baidu.com 服務器上的 /folder/index.html 文件。不過,在實際應用中,有的時候 URI 並不是這麼清晰,比如下面這個:

http://wwww.baidu.com

這種 URI 並沒有直接指定要訪問哪個文件,像這種沒有路徑的情況,就代表訪問根目錄下預先設置的默認文件,一般就是 /index.html, /default.html 一類的文件,在 Java 中,我們也可以在 web.xml 中來配置這個默認文件。

有的時候我們還有可能遇到下面這種地址:

http://www.baidu.com/folder/

這個 URI 以一個 / 結尾,表示 folder 是一個目錄,我們要訪問的是這個目錄下的文件,但是又沒有說明是這個目錄下的哪個文件,此時依然是採用該目錄下 index.html 或者 default.html 一類的文件。

有的時候,我們還可以看到下面這種 URI:

http://www.baidu.com/folder

即 folder 後面沒有

/ ,此時會先將 folder 當作一個資源去訪問(比如一個名為 folder 的 Servlet ),如果沒有名為 folder 的資源,那麼瀏覽器會自動在 folder 後面加上一個 / ,此時地址變為 http://www.baidu.com/folder/ ,folder 是一個目錄,然後就會去嘗試訪問 folder 目錄下的 index.html 或者 default.html 。 注意這種自動調整隻在瀏覽器中存在,如果你的項目是一個手機 App 或者你是一個 Ajax 請求,則不會有這種調整,即沒寫 / 就當做具體資源來對待,如果該資源不存在,就會報 404 ,寫了/ 就當目錄來對待。(OkHtpp3中是這樣)

有的時候我們還可能見到下面這種URI:

http://www.baidu.com/

這個和我們介紹的第一種情況很類似,只是後面多了一個 / ,這個 / 表示我們要訪問的是根目錄,但是沒有指定根目錄下的文件,默認就是根目錄下的 index.html 或者 default.html 。

OK,經過上面的介紹,小夥伴對 URI 最後面的 **/** 已經有了清晰的認識了吧?這個東西不可以隨意省略,有 / 和沒有 / ,訪問結果有可能是天壤之別。

  1. 《網絡是怎樣連接的》


分享到:


相關文章: