该系列主要围绕前端一些基础性的内容进行回顾整理,为日益纷繁的各类框架打下一个基础的底子,便于理解一些框架内容。
今天我们主要来回顾一下有关于URI
和URL
相关的内容。
URI是什么
统一资源标识符(Uniform Resource Identifier,URI
),允许用户对网络中的资源通过特定的协议进行交互操作。RFC2396
文档对Uniform Resource Identifier
各部分的定义如下。
Uniform
:规定统一的语法格式,以方便处理多种不同类型的资源,而无须根据上下文环境来识别资源类型。Resource
:可标识的任何资源。资源不仅可以为单一对象,也可以为多个对象的集合体。Identifier
:表示可标识的对象,也称为标识符。
在一般情况下,URI
为由某个协议方案表示的资源的定位标识符。协议方案是指访问资源时所使用的协议类型名称。HTTP
就是协议方案的一种,除此之外,还有FTP
、file
、TELNET
等30种标准URI协议方案。协议方案由互联网号码分配局(IANA)管理颁布。URI使用字符串标识某一互联网资源,常用的URL
作为URI
的子集,表示某一互联网资源的地点。
URI
的通用语法由5个组件组成:
URI = scheme:[//authority]path[?query][#fragment]
在URI语法中:
scheme
为协议方案名,在使用HTTPS
或HTTP
等协议方案名时不区分大小写,最后一个符号为冒号“:”。协议方案名也可使用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的关系是什么呢
统一资源名称(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编码。常用的编码方法主要有encodeURI
和encodeURIComponent
。
encodeURI和encodeURIComponent
encodeURI()
和encodeURIComponent()
都是Javascript中对URL编码的函数。
区别在于:
encodeURI
是W3C
的标准(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
相比encodeURIComponent
,encodeURI
被用作对一个完整的URI
进行编码,而encodeURIComponent
则被用作对URI
的一个组件或者URI
中的一个片段进行编码。从上面的编码示例来看,encodeURIComponent
编码的字符范围要比encodeURI
大。
小结
以上就是针对URI
和URL
以及相关编码方法的回顾梳理。在日常的前端开发中,URL
等概念是我们经常提及的,而相关的编码转码方法也在我们的日常开发中经常会用到。希望本次回顾也能够帮助大家重温加深一下这些知识。
参考资料
-《深入理解React Router从原理到实战》
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。