前端基础回归-URI和URL

该系列主要围绕前端一些基础性的内容进行回顾整理,为日益纷繁的各类框架打下一个基础的底子,便于理解一些框架内容。

今天我们主要来回顾一下有关于URIURL相关的内容。

URI 是什么

统一资源标识符(Uniform Resource Identifier,URI),允许用户对网络中的资源通过特定的协议进行交互操作。RFC2396文档对Uniform Resource Identifier各部分的定义如下。

  • Uniform:规定统一的语法格式,以方便处理多种不同类型的资源,而无须根据上下文环境来识别资源类型。

  • Resource:可标识的任何资源。资源不仅可以为单一对象,也可以为多个对象的集合体。

  • Identifier:表示可标识的对象,也称为标识符。

在一般情况下,URI为由某个协议方案表示的资源的定位标识符。协议方案是指访问资源时所使用的协议类型名称。HTTP就是协议方案的一种,除此之外,还有FTPfileTELNET等 30 种标准 URI 协议方案。协议方案由互联网号码分配局(IANA)管理颁布。URI 使用字符串标识某一互联网资源,常用的URL作为URI的子集,表示某一互联网资源的地点。

URI的通用语法由 5 个组件组成:

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

在 URI 语法中:

  • scheme为协议方案名,在使用HTTPSHTTP等协议方案名时不区分大小写,最后一个符号为冒号“:”。协议方案名也可使用javascript:、data:指定脚本程序或数据。
  • path为带层次的文件路径,指定服务器上的文件路径,以访问特定的资源。
  • query为查询字符串,针对指定路径的文件资源,可使用查询字符串传入任意查询参数。
  • fragment为片段标识符,通常标记已获取资源的子资源,为可选项。
  • authority可以由以下 3 分布组成:
1
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 个保留字符:

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

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进行编码,如:

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

相比encodeURIComponentencodeURI被用作对一个完整的URI进行编码,而encodeURIComponent则被用作对URI的一个组件或者URI中的一个片段进行编码。从上面的编码示例来看,encodeURIComponent编码的字符范围要比encodeURI大。

小结

以上就是针对URIURL以及相关编码方法的回顾梳理。在日常的前端开发中,URL等概念是我们经常提及的,而相关的编码转码方法也在我们的日常开发中经常会用到。希望本次回顾也能够帮助大家重温加深一下这些知识。

参考资料

-《深入理解 React Router 从原理到实战》

查看评论