【发布时间】:2019-05-17 06:33:24
【问题描述】:
为什么下面的代码不会在运行时将 URISyntaxException 作为非法 URI 抛出?
new URI("http:us//er:ps//w@si//te.c/om/dir1/di//r2/fi//le.txt#frag//ment");
// or same with "http:// ... "
new URI("http://us//er:ps//w@si//te.c/om/dir1/di//r2/fi//le.txt#frag//ment");
根据wikipedia,“/”是一个保留(特殊)字符,应以百分比编码(也称为 URL 编码)为%2F
保留字符
/,例如,如果用在 URI 的“路径”组件中,则具有作为路径之间分隔符的特殊含义段。 如果,根据给定的URI方案,/需要在路径段中,那么%2F或%2f这三个字符必须是在段中使用,而不是原始的/。
但 URI 构造函数不允许对其进行 URL 编码!
Wikipedia defines URI 格式如下(RFC 3986,section 3 (2005)):
URI = scheme:[//authority]path[?query][#fragment]
并且 URI 构造函数允许在任何组件中直接使用/(不是百分比编码的)(也许方案除外)。
URI Javadoc states:
此构造函数完全按照 RFC 2396 附录 A 中的语法,以下偏差除外: ...
other 类别中的字符在 RFC 2396 中允许使用 允许转义八位组,即在用户信息、路径、查询中, 和片段组件,以及在权限组件中,如果 权限是基于注册表的。这允许 URI 包含 Unicode 超出 US-ASCII 字符集的字符。
这允许非百分比编码的“其他”字符(请参阅上面的 wiki 链接以了解 保留/未保留/其他字符说明),例如 ɷ(非 ASCII),因此这与保留无关正斜杠等字符。
但无论如何 - 为什么和为什么?
附:维基百科解释了为什么我们可以在其他组件中使用正斜杠,但为什么我们可以在路径组件(目录名、文件名)中使用它仍然不清楚。
在特定上下文中没有保留目的的保留字符也可以是百分比编码的,但在语义上与没有保留的字符没有区别。
在 URI 的“查询”组件中(在 ? 字符之后的部分),对于 例如,/ 仍被视为保留字符 但通常 没有保留的目的,除非特定的 URI 方案说 否则。字符不需要进行百分比编码 没有保留的用途。
【问题讨论】:
-
您特别希望哪些斜杠会导致异常?
-
路径组件中的任何单个 / ,这里有两种情况: .... di//r2/fi//le.txt ... - 在目录 dir2 名称的中间和中间文件 file.txt 名称。
-
好的,所以问题是为什么 URI 的路径元素允许 /。在第一个维基百科注释中,您清楚地表明 / 是路径段之间的分隔符。您必须转义路径段中的那些。你不能逃避那些分隔路径段的那些。
-
“维基百科定义 URI 格式如下……”不完全。 Wikipedia 和 URI 规范将 分层 URI 定义为
scheme:[//authority]path[?query][#fragment]。由于 URI 中http:之后的字符不是斜杠,因此您根本没有分层 URI,因此唯一的字符限制是规范术语 uric 的内容,其中包括斜杠。