哪些字符会使URL无效?

哪些字符会使URL无效?

这里大部分现有答案都不切实际,因为它们完全忽略了像以下这样的地址在实际使用中的情况:

https://en.wikipedia.org/wiki/Möbius_strip 或者

https://zh.wikipedia.org/wiki/Wikipedia:关于中文维基百科/en。

首先,术语方面的扯皮。这些地址是什么?它们是有效的URL吗?

历史上的答案是“否”。根据2005年RFC 3986的规定,这样的地址不是URI(因此也不是URL,因为URL是URI的一种类型)。根据2005年IETF标准的术语,我们应该正确地称它们为IRI(国际化资源标识符),如RFC 3987所定义,它们在技术上不是URI,但可以通过在IRI中百分号编码所有非ASCII字符来简单地转换为URI。

根据现代规范,答案是“是”。WHATWG Living Standard将以前被称为“URI”或“IRI”的所有内容都归类为“URL”。这使得规范术语与未阅读规范的普通人使用“URL”的方式相一致,这是规范的目标之一。

什么样的字符在WHATWG Living标准下是允许的?

根据这种“URL”新定义,哪些字符是被允许的?在URL的许多部分中,比如查询字符串和路径,我们可以使用任意的"URL units",其中包括

URL code points 和 percent-encoded bytes。

那么,“URL code points”是什么意思?

“URL 码点”是指 ASCII 字母数字、U+0021 (!)、U+0024 ($)、U+0026 (&)、U+0027 (')、U+0028 左圆括号、U+0029 右圆括号、U+002A (*)、U+002B (+)、U+002C (,)、U+002D (-)、U+002E (.)、U+002F (/)、U+003A (:)、U+003B (;)、U+003D (=)、U+003F (?)、U+0040 (@)、U+005F (_)、U+007E (~) 以及码点从 U+00A0 到 U+10FFFD(包括两端的码点),但不包括代理项和非字符。(请注意,“URL 码点”列表不包括百分号 %,但如果它们是百分编码序列的一部分,则可以在“URL 码元”中使用百分号 %。)

我能发现规范允许使用任何不在这个集合中的字符的唯一地方是在host中,其中IPv6地址被括在[和]字符中。在URL的其他任何地方,要么允许URL单元,要么允许一些更加严格的字符集。

旧版RFC允许使用哪些字符?

为了了解历史背景,并且因为在此处的答案中没有完全探讨,让我们来看看旧版规范下允许使用哪些字符。

首先,我们有两种类型的RFC 3986 保留字符:

:/?#[]@,这些字符是URI的一般语法,由RFC 3986定义。

!$&'()*+,;=,这些字符不是RFC的通用语法的一部分,但是被保留用作特定URI方案的语法组成部分。例如,分号和逗号被用作data URIs的语法的一部分,&和=被用作查询字符串中普遍使用的?foo=bar&qux=baz格式的一部分(该格式未由RFC 3986指定)。

上述任何保留字符都可以在URI中合法地使用而不进行编码,既可以用于其语法目的,也可以用作数据中的文字字符,某些情况下,这种用法不会被误解为该字符用于其语法目的。(例如,尽管/在URL中具有语法意义,但您可以在查询字符串中未经编码地使用它,因为它在查询字符串中没有意义。)

RFC 3986 还指定了一些未保留字符,这些字符可以直接用于表示数据而无需进行任何编码:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~

最后,%字符本身可以用于百分号编码。

这意味着以下ASCII字符在URL中是禁止出现的:

控制字符(字符0-1F和7F),包括换行、制表符和回车。

"<>^`{|}

除此之外,ASCII中的其他字符都可以合法地出现在URL中。

然后RFC 3987通过以下Unicode字符范围扩展了未保留字符集:

%xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF

/ %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD

/ %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD

/ %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD

/ %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD

/ %xD0000-DFFFD / %xE1000-EFFFD

最新的Unicode 块定义看起来与旧规范中的这些块选择非常奇怪和武断;这可能是因为在RFC 3987撰写十年后,这些块已经被添加进去了。

最后,值得注意的是仅仅知道哪些字符可以在URL中合法出现并不足以识别某个给定的字符串是否为合法的URL,因为某些字符仅在URL的特定部分中合法。例如,保留字符[和]在URL中作为IPv6文字主机的一部分是合法的,如http://[1080::8:800:200C:417A]/foo,但在任何其他情况下都不合法,因此OP的示例http://example.com/file[/].html是非法的。

相关推荐

足彩缩水怎么样
beat365正版唯一官网

足彩缩水怎么样

📅 08-13 👁️ 5377
14999元的电变公路车 野兽SPEEDX LEOPARD PRO
beat365正版唯一官网

14999元的电变公路车 野兽SPEEDX LEOPARD PRO

📅 07-11 👁️ 985