天天看點

【網絡】HTTP 協定中 URI 和 URL 有什麼差別?

HTTP定義

超文本傳輸協定(Hyper Text Transfer Protocol,HTTP)是一個簡單的請求-響應協定,它通常運作在TCP之上。它指定了用戶端可能發送給伺服器什麼樣的消息以及得到什麼樣的響應。請求和響應消息的頭以ASCII形式給出

HTTP是用于分布式、協作式和超媒體資訊系統的應用層協定,是網際網路上應用最為廣泛的一種網絡傳輸協定,所有的 WWW 檔案都必須遵守這個标準。

HTTP基于TCP/IP通信協定來傳遞資料(HTML 檔案, 圖檔檔案, 查詢結果等)。

更多内容可參考 ​​菜鳥教程HTTP​​

URI 和URL定義

URL:(Uniform/Universal Resource Locator 的縮寫,統一資源定位符)。

URI:(Uniform Resource Identifier 的縮寫,統一資源辨別符)(代表一種标準)。

與之相關的還有一種定義:URN = Uniform Resource Name 統一資源名稱

關系:

URI 屬于 URL 更高層次的抽象,一種字元串文本标準。

就是說,URI 屬于父類,而 URL 屬于 URI 的子類。URL 是 URI 的一個子集。

二者的差別在于,URI 表示一種标準來定義一個資源。

而 URL 怎麼去實作這個标準,同時說明要如何通路這個資源(http://)。

如下圖,通過各種協定去通路資源

【網絡】HTTP 協定中 URI 和 URL 有什麼差別?

浏覽器位址欄裡通路網站的位址認為是URL就好了,也就是以HTTP/HTTPS開頭的URI子集。

知乎高贊回答如此大白話:

URI是抽象的定義,不管用什麼方法表示,隻要能定位一個資源,就叫URI,本來設想的的使用兩種方法定位:

1,URL,用位址定位;

2,URN ,用名稱定位。

舉個例子:去村子找個具體的人(URI),如果用位址:某村多少号房子第幾間房的主人 就是URL, 如果用身份證号+名字去找就是URN了。結果就是 目前WEB上就URL流行開了,平常見的URI 基本都是URL。

URL 标準格式

scheme://host[:port#]/path/.../[;url-params][?query-string][#anchor]      
scheme //有我們很熟悉的http、https、ftp以及著名的ed2k,迅雷的thunder等。
host   //HTTP伺服器的IP位址或者域名
port#  //HTTP伺服器的預設端口是80,這種情況下端口号可以省略。如果使用了别的端口,必須指明,例如tomcat的預設端口是8080 http://localhost:8080/
path   //通路資源的路徑
url-params  //所帶參數 
query-string    //發送給http伺服器的資料
anchor //錨點定位      

Java中的URI和URL

Java裡面的注釋定義

A URI is a uniform resource identifier while a URL is a uniform

resource locator. Hence every URL is a URI, abstractly speaking, but

not every URI is a URL. This is because there is another subcategory

of URIs, uniform resource names (URNs), which name resources but do

not specify how to locate them. The mailto, news, and isbn URIs shown

above are examples of URNs.

翻譯過來就是

URI 是統一資源辨別符,而 URL 是統一資源定位符。 是以,抽象地說,每個 URL 都是一個 URI,但并不是每個 URI 都是一個URL。 這是因為有另一個 URI 子類别,統一資源名稱(URN),它命名資源但不指定如何定位它們

但是在Java的實作裡面并沒有URI和URL的繼承關系啥的,他們兩個都是final類

public final class URI implements Comparable<URI>, Serializable      
public final class URL implements java.io.Serializable      

URI類中提供了轉換到URL的方法

public URL toURL()
        throws MalformedURLException {
        if (!isAbsolute())
            throw new IllegalArgumentException("URI is not absolute");
        return new URL(toString());
    }      

URL類同樣也提供了轉換到URI的方法

public URI toURI() throws URISyntaxException {
        URI uri = new URI(toString());
        if (authority != null && isBuiltinStreamHandler(handler)) {
            String s = IPAddressUtil.checkAuthority(this);
            if (s != null) throw new URISyntaxException(authority, s);
        }
        return uri;
    }      

Java中對URI和URL的操作

public class UriAndUrl {



    public static void urlTest(String str) throws Exception{

        URL url = new URL(str);
        System.out.println("URL:                  " + url.toString());
        System.out.println("protocol:        " + url.getProtocol());
        System.out.println("Authority:      " + url.getAuthority());
        System.out.println("file name:      " + url.getFile());
        System.out.println("host:                " + url.getHost());
        System.out.println("path:                " + url.getPath());
        System.out.println("port:                " + url.getPort());
        System.out.println("default port:" + url.getDefaultPort());
        System.out.println("query:              " + url.getQuery());
        System.out.println("ref:                  " + url.getRef());
    }

    public static void uriTest(String str) throws Exception{
        URI uri = new URI(str);
        System.out.println("URI:                  " + uri.toString());
        System.out.println("scheme             : " + uri.getScheme());
        System.out.println("SchemeSpecificPart : " + uri.getSchemeSpecificPart());
        System.out.println("Authority          : " + uri.getAuthority());
        System.out.println("host               : " + uri.getHost());
        System.out.println("port               : " + uri.getPort());
        System.out.println("path               : " + uri.getPath());
        System.out.println("query              : "  + uri.getQuery());
        System.out.println("fragment           : " + uri.getFragment());
    }

    public static void main(String[] args) throws Exception {
     
        System.out.printf("---------------------------------------\n");
        UriAndUrl.uriTest(str);
        System.out.printf("---------------------------------------\n");
        UriAndUrl.urlTest(str);
    }

}      

輸出結果

References:

  • ​​https://www.zhihu.com/question/21950864​​
  • ​​https://www.zhihu.com/question/21950864/answer/158161453​​
  • ​​https://baike.baidu.com/item/HTTP/243074?fr=aladdin​​
  • ​​https://www.runoob.com/http/http-tutorial.html​​