我的Chrome版本101允许我打开
https://%65%78%61%6D%70%6C%65%2E%63%6F%6D
(https://example.com
,除https://
外编码。
但不是
https://%65%78%61%6D%70%6C%65%2E%63%6F%6D%2F%74%65%73%74
(https://example.com/test
,路径分隔符/
也编码)。
根据最新规范,URL 的哪些部分和哪些字符可以进行 URL 编码?
我所说的">部分"是指方案、用户名、密码、主机、端口、路径、查询、片段、.
、:
、//
、@
、?
、#
等。
我所说的"什么角色"是指"在什么部分具有什么价值的角色"。
根据规范
来自 RFC 3986。
<小时 />2.1.百分比编码
....
大写十六进制数字"A"到">pct-encoded = "%" HEXDIG HEXDIG
F"分别等效于小写数字"a"到"f"。如果两个 URI 仅在百分比编码八位字节中使用的十六进制数字的情况下不同,则它们是等效的。 为了保持一致性,URI 生成者和规范化程序应对所有百分比编码使用大写十六进制数字。
- 百分比编码不区分大小写。
2.2.保留字符
reserved = gen-delims / sub-delims gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
保留字符的目的是提供一组可与 URI 中的其他数据区分开来的分隔字符。在将保留字符替换为其相应的百分比编码八位字节时不同的 URI 并不等效。对保留字符进行百分比编码,或对对应于保留字符的百分号编码八位字节进行解码,将更改大多数应用程序解释 URI 的方式。因此,保留集中的字符受到规范化保护,因此可以安全地由特定于方案和特定于生产者的算法用于分隔 URI 中的数据子组件。
保留字符(
gen-delims
)的子集用作第3节中描述的通用URI组件的分隔符。组件的 ABNF 语法规则不会直接使用保留或gen-delims
规则名称;相反,每个语法规则都会列出该组件中允许的字符(即,不分隔它),并且保留集中的任何字符都被"保留"用作组件中的子组件分隔符。此规范仅定义最常见的子组件;其他子组件可以由 URI 方案的规范定义,也可以由 URI 的取消引用算法的特定于实现的语法定义,前提是此类子组件由该组件中允许的保留集中的字符分隔。生成 URI 的应用程序应对与保留集中的字符对应的数据八位字节进行百分比编码,除非 URI 方案明确允许这些字符表示该组件中的数据。如果在 URI 组件中找到保留字符,并且该字符没有已知的分隔角色,则必须将其解释为表示对应于该字符在 US-ASCII 中的编码的数据八位字节。
- 字符"
:/?#[]@!$&'()*+,;=
"是保留字符。
URL - 方案规范将语法 URL 分隔符定义为保留字符中的某些字符。
- 语法 URL 分隔符不是百分比编码的。
- 不是语法 URL 分隔符的保留字符可以进行百分比编码,也可以不进行百分比编码,但建议使用百分比编码。
2.3.非保留字符
URI 中允许但没有保留用途的字符称为非保留字符。其中包括大写和小写字母、十进制数字、连字符、句点、下划线和波浪号。
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
在将非保留字符替换为其相应的百分比编码的 US-ASCII 八位字节方面不同的 URI 是等效的:它们标识相同的资源。但是,URI 比较实现并不总是在比较之前执行规范化(请参阅第 6 节)。为了保持一致性,URI 生产者不应创建
ALPHA
(%41
–%5A
和%61
–%7A
)、DIGIT
(%30
–%39
)、连字符 (%2D
)、句点 (%2E
)、下划线 (%5F
) 或波浪号 (%7E
) 范围内的百分比编码八位字节,并且在 URI 中找到时,应由 URI 规范化器解码为其相应的非保留字符。
6.规范化和比较
。URI 比较是为某些特定目的而执行的。出于不同目的比较 URI 的协议或实现通常会受到不同的设计权衡,即在减少别名标识符方面应花费多少精力。本节介绍可用于比较 URI 的各种方法、它们之间的权衡以及可能使用它们的应用程序类型。
- URL 中允许的字符而不是保留的字符(即"
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~
")是非保留字符。 - 非保留字符可以是百分比编码,也可以不是,但建议不要。
总结
- 语法 URL 分隔符→不能进行百分比编码。
- 除此之外,→可以是百分比编码,也可以不编码。
- 百分比编码不区分大小写。
实现将如何执行
某些实现不会执行完整、广泛的 URL 规范化。例如,"%68%74%74%70%73://example.com
"是规范中的有效网址,但Chrome(版本101)在放入全能栏时不会将其规范化为"https://example.com
"。