答案并不简单。
以下内容摘自 RFC 3986 的第 3.2.2 节:
由 Internet 协议文字地址(版本 6)标识的主机
[RFC3513] 或更高版本,通过括起 IP 文字来区分
在方括号(“[”和“]”)内。这是唯一的地方
URI 语法中允许使用方括号字符。
This seems通过断然声明 URI 中的其他任何地方都不允许使用方括号来回答这个问题。但方括号字符和百分号编码的方括号字符之间存在差异。
以下内容摘自 RFC 3986 第 3 节的开头:
- 语法组件
通用 URI 语法由以下层次结构序列组成
称为方案、权限、路径、查询和的组件
分段。
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
所以“查询”是“URI”的一个组成部分。
以下内容摘自 RFC 3986 的 2.2 节:
2.2.保留字符
URI 包括由以下分隔的组件和子组件
“保留”集中的字符。这些字符被称为
“保留”,因为它们可能(或可能不)被定义为分隔符
通用语法,通过每个特定于方案的语法,或通过
URI 解除引用算法的特定于实现的语法。
如果 URI 组件的数据与保留的数据冲突
字符的用途作为分隔符,那么冲突的数据必须
在形成 URI 之前进行百分比编码。
reserved = gen-delims / sub-delims
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
因此,方括号可能会出现在查询字符串中,但前提是它们是百分比编码的。除非不是,否则将在 2.2 节中进一步解释:
生成 URI 的应用程序应对数据八位字节进行百分比编码
对应于保留集中的字符,除非这些字符
URI 方案特别允许表示其中的数据
成分。如果在 URI 组件中找到保留字符并且
该字符没有已知的分隔角色,那么它一定是
解释为表示对应的数据八位字节
US-ASCII 中的字符编码。
因此,由于方括号仅允许在“主机”子组件中使用,因此它们“应该”在其他组件和子组件中进行百分比编码,在本例中是在“查询”组件中,除非 RFC 3986 明确允许未编码的方括号表示中的数据查询组件,但它没有。
但是,如果“生成 URI 的应用程序”未能执行其“应该”执行的操作(在查询中保留方括号未编码),则 URI 的读者不会直接拒绝该 URI。相反,方括号将被视为属于查询组件的数据,因为它们不用作该组件中的分隔符。
这就是为什么,例如,当 PHP 接受未编码和百分比编码的方括号作为查询字符串中的有效字符,甚至为它们分配特殊用途时,并不违反 RFC 3986。然而,试图利用此漏洞而不对方括号进行百分比编码的作者似乎违反了 RFC 3986。