前端基礎迴歸-URI和URL

前端榮耀發表於2022-01-26
該系列主要圍繞前端一些基礎性的內容進行回顧整理,為日益紛繁的各類框架打下一個基礎的底子,便於理解一些框架內容。

今天我們主要來回顧一下有關於URIURL相關的內容。

URI是什麼

統一資源識別符號(Uniform Resource Identifier,URI),允許使用者對網路中的資源通過特定的協議進行互動操作。RFC2396文件對Uniform Resource Identifier各部分的定義如下。

  • Uniform:規定統一的語法格式,以方便處理多種不同型別的資源,而無須根據上下文環境來識別資源型別。
  • Resource:可標識的任何資源。資源不僅可以為單一物件,也可以為多個物件的集合體。
  • Identifier:表示可標識的物件,也稱為識別符號。

在一般情況下,URI為由某個協議方案表示的資源的定位識別符號。協議方案是指訪問資源時所使用的協議型別名稱。HTTP就是協議方案的一種,除此之外,還有FTPfileTELNET等30種標準URI協議方案。協議方案由網際網路號碼分配局(IANA)管理頒佈。URI使用字串標識某一網際網路資源,常用的URL作為URI的子集,表示某一網際網路資源的地點。

URI的通用語法由5個元件組成:

URI = scheme:[//authority]path[?query][#fragment]

在URI語法中:

  • scheme為協議方案名,在使用HTTPSHTTP等協議方案名時不區分大小寫,最後一個符號為冒號“:”。協議方案名也可使用javascript:、data:指定指令碼程式或資料。
  • path為帶層次的檔案路徑,指定伺服器上的檔案路徑,以訪問特定的資源。
  • query為查詢字串,針對指定路徑的檔案資源,可使用查詢字串傳入任意查詢引數。
  • fragment為片段識別符號,通常標記已獲取資源的子資源,為可選項。
  • authority可以由以下3分佈組成:
authority = [userinfo@]host[:port]

authority中,userinfo作為登入資訊,通常形式為指定使用者名稱和密碼,當從伺服器獲取資源時作為身份認證憑證使用。userinfo為可選項。伺服器地址host在使用絕對路徑URI時需指定訪問的伺服器地址,地址可以為被DNS解析的域名,如example.com,或者192.168.1.1的IPv4地址及用方括號括起來的IPv6地址[0:0:0:0:0:0:0:1]port為伺服器連線的網路埠號,作為可選項,如果不指定,則自動使用預設的埠號。

URL是什麼

統一資源定位器(UniformResourceLocators,URL)作為URI的一種,如同網路的門牌,標識了一個網際網路資源的“住址”,如<http://www.example.com>表示通過HTTP協議從主機名為www.example.com的主機上獲取首頁資源。

URL的語法定義與URI是一致的,它屬於URI的一個子集。

統一資源名稱(Uniform Resource Name)也是標準格式的URI,指的是資源而不指定其位置或是否存在。鑑於該概念在日常前端的範圍內接觸較少,僅作為了解即可,有興趣的可以自行查閱相關內容。

URI和URL的關係是什麼呢

URI和URL的關係

統一資源名稱(Uniform Resource Name)也是標準格式的URI,指的是資源而不指定其位置或是否存在。鑑於該概念在日常前端的範圍內接觸較少,僅作為了解即可,有興趣的可以自行查閱相關內容。

借用一張圖來理解他們之間的關係:URI可以分為URL,URN或同時具備locators 和names特性的一個東西。URN作用就好像一個人的名字,URL就像一個人的地址。換句話說:URN確定了東西的身份,URL提供了找到它的方式。

大白話來說,就是URI是抽象的定義,不管用什麼方法表示,只要能定位一個資源,就叫URI。本來設想的的使用兩種方法定位:1、URL,用地址定位;2、URN 用名稱定位。

舉個例子:去村子找個具體的人(URI),如果用地址:某村多少號房子第幾間房的主人-就是URL; 如果用身份證號+名字去找-就是URN了。

瀏覽器URI編碼

URI編碼使用的是百分號編碼(Percent-encoding)。對於需要編碼的字元,將其表示為兩個十六進位制的數字,然後在其前面放置轉義字元“%”,並替換原字元相應位置進行編碼。

URI中只允許包含未保留字元及所有保留字元。其中,未保留字元包含英文字母(a~z,A~Z),數字(0~9),-、_、.、~4個特殊字元,共66個。對於未保留字元,不需要進行百分號編碼。保留字元是那些具有特殊含義的字元。RFC 3986 文件中規定了18個保留字元:

!*'();:@&=+$,/?#[]

URI中,保留字元有特殊的意義,如“?”表示查詢,“#”表示片段標識。如果希望保留字元不表示特定的意義,僅表示一般字元,那麼需要對保留字元進行URL編碼。常用的編碼方法主要有encodeURIencodeURIComponent

encodeURI和encodeURIComponent

encodeURI()encodeURIComponent()都是Javascript中對URL編碼的函式。

區別在於:

  • encodeURIW3C的標準(RFC 3986),不對ASCII字母和數字進行編碼,不對20個ASCII標點符號(-、_、.、!、~、*、'、(、)、;、/、?、:、@、&、=、+、$、,、#)進行編碼。對於66個未保留字元,18個保留字元,除去2個不安全的保留字元“[”“]”encodeURI的不編碼集為82個。對於非ASCII字元,encodeURI需要將其轉換為UTF-8編碼位元組序,然後在每個位元組前面放置轉義字元(%)進行百分號編碼,並置入URI中的相應位置。

    UTF-8:UTF-8具有無位元組序要求、單位元組特性節約記憶體、向後相容ASCII、錯誤相容性好等優點。一個純ASCII字串也是一個合法的UTF-8字串,所以現存的ASCII文字不需要轉換。為傳統的擴充套件ASCII字符集設計的軟體通常可以不經修改或經過很少修改就能與UTF-8一起使用。
  • encodeURIComponent假定引數是URI的一部分(比如協議、主機名、路徑或查詢字串),因此,encodeURIComponent將轉義除字母、數字、“(”、“)”、“.”、“!”、“~”、“*”、“'”、“-”和“_”外的所有字元。例如,對“name=val&key=”進行encodeURIComponent編碼後結果為“"name%3Dval%26key%3D"”。對於URL組成部分中的特殊字元,通常需要使用encodeURIComponent進行編碼,如:

    name=encodeURIComponent('val&key=')
    // name=val%26key%3D

相比encodeURIComponentencodeURI被用作對一個完整的URI進行編碼,而encodeURIComponent則被用作對URI的一個元件或者URI中的一個片段進行編碼。從上面的編碼示例來看,encodeURIComponent編碼的字元範圍要比encodeURI大。

小結

以上就是針對URIURL以及相關編碼方法的回顧梳理。在日常的前端開發中,URL等概念是我們經常提及的,而相關的編碼轉碼方法也在我們的日常開發中經常會用到。希望本次回顧也能夠幫助大家重溫加深一下這些知識。

參考資料

-《深入理解React Router從原理到實戰》

相關文章