为啥 %(百分比)在 RFC 3986(URI 语法)中不被视为保留字符?

Posted

技术标签:

【中文标题】为啥 %(百分比)在 RFC 3986(URI 语法)中不被视为保留字符?【英文标题】:Why isn't % (percent) considered a reserved character in RFC 3986 (URI Syntax)?为什么 %(百分比)在 RFC 3986(URI 语法)中不被视为保留字符? 【发布时间】:2011-12-31 20:43:46 【问题描述】:

显然 % 需要编码。 wikipedia article on the standard 说:

因为百分号(“%”)字符用作指示符 百分比编码的八位字节,它必须被百分比编码为“%25” 八位字节用作 URI 中的数据。

为什么它不被列为保留字符?显然,它是为了在 URI 的上下文中表示特殊的东西而保留的......

【问题讨论】:

【参考方案1】:

“保留”字符旨在用作 URI 不同部分之间的分隔符。百分号不用于那个——不能用于那个——因为它用于百分比编码。

指出有一个单独的“未保留”字符列表可能有助于澄清问题,而百分号也不是其中之一:

      unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"

(来自http://www.ietf.org/rfc/rfc3986.txt,第 12 页底部)。换句话说,在 URI 的上下文中,“保留”具有比人们预期的更具体的含义。 :-)

【讨论】:

【参考方案2】:

保留字符是在 在 URI 中具有特殊含义的字符,因此如果它们用于以外的其他内容,则需要以某种方式进行转义 他们的特殊目的。

百分比字符在 URI 中具有特殊含义——这使它成为转义/编码字符的好选择。

它被用来进行编码的事实是百分比本身需要通过百分比编码来转义的唯一原因。

这类似于字符转义,其中反斜杠 \ 本身必须被转义 \\ 只是因为它是在\t\n 中选择进行初始转义的字符

【讨论】:

嗯...如果在 URI 中,百分比字符用于表示其他字符,并且只允许用于该目的,对我来说这构成了特殊含义一个URI,不是吗? :-) @John - No. :-) 如果在 URI 中使用百分比字符,则仅表示百分比字符,就像 A 表示 A 一样。它在 URI 中不是特殊的,也不是保留的。转义/编码的行为使它变得特别。假设~ 被选为转义字符。那么&还是要转义,但是%可以正常使用;这就是您如何判断 & 具有特殊含义但 % 没有 - 并且 ~ 必须被转义,因为它对于 encoding 而不是 是特殊的URI 嗯。但是所有的 URI 都使用百分比编码,实际上必须使用百分比编码,对吧? @John 即使这是真的,% 仍保留为 编码方案 的一部分,而不是保留在 URI 方案跨度> 我想我不知道“保留”和“方案”是什么意思:)【参考方案3】:

通过参与语法规则pct-encoded,百分号已被保留。此外,这一段似乎对这个主题很有启发:

URI 由一组有限的字符组成,这些字符由数字、字母和一些图形符号组成。这些字符的保留子集可用于分隔 URI 中的语法组件,而其余字符(包括未保留集和不用作分隔符的保留字符)定义每个组件的标识数据。

这表明百分比符号本身确实是为百分比编码保留的(因为它不分隔 URI 中的语法组件)。您的原始解释是正确的,我认为这只是语义问题。

【讨论】:

以上是关于为啥 %(百分比)在 RFC 3986(URI 语法)中不被视为保留字符?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 Uri.EscapeDataString 符合 RFC 3986

Java 和 RFC 3986 URI 编码

根据 RFC 3986 的无效 URI 示例

当相对 URI 包含空路径时,Java 的 URI.resolve 是不是与 RFC 3986 不兼容?

Java URL 类 getPath()、getQuery() 和 getFile() 与 RFC3986 URI 语法不一致

如何对 RFC 3986 字符串进行转义