这里的大多数现有答案都是不切实际的,因为它们完全忽略了地址在现实世界中的用法,例如:

条带或https://zh.wikipedia.org/wiki/Wikipedia:关于中文维基百科/en。第一,对术语的偏误。这些地址是什么?它们是有效的URL吗?

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

根据现代规范,答案是“是”。WHATWG生活水平简单地将以前被称为“URI”或"IRIs“的所有内容归类为”URL“。这与未阅读规范的正常人使用"URL“一词是一致的,这是规范的目标之一。

根据WHATWG的生活标准,哪些角色是允许的?

根据"URL“这个较新的意思,哪些字符是允许的?在URL的许多部分,例如查询字符串和路径中,我们可以使用任意的"URL单位“,这是

URL代码点和百分比编码字节.

什么是"URL代码点“?

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+003A (@)、(_)、(~),以及到范围内的代码点,包括代孕者和非字符。

(请注意,"URL代码点“列表不包括%,但如果它们是百分比编码序列的一部分,则允许在"URL代码单元”中使用%。)

在规范允许使用不在此集中的任何字符的唯一位置是在主机中,其中IPv6地址以[和]字符括起来。在URL中的其他地方,要么允许URL单元,要么允许一些更严格的字符集。

旧的RFCs允许哪些字符?

为了历史的考虑,并且由于在这里的答案中没有对它进行充分的探索,让我们在旧的规范下进行检查。

首先,我们有两种RFC 3986 保留字符。

:/?#[]@,,它是RFC 3986中定义的URI的泛型语法的一部分。!$&'()*+,;=,不是RFC泛型语法的一部分,而是保留用于特定URI方案的语法组件。例如,分号和逗号作为数据URI语法的一部分,而&和=作为查询字符串中普遍存在的?foo=bar&qux=baz格式的一部分( RFC 3986没有指定)。上述任何保留字符都可以合法地在URI中使用,而无需编码,既可以用于语法目的,也可以作为数据中的文字字符使用,而在某些地方,这种使用不能被误解为为其语法目的服务的字符。(例如,尽管/在URL中具有语法意义,但您可以在查询字符串中使用它,因为它在查询字符串中没有意义。)

RFC 3986还指定了一些非保留字符,这些字符总是可以简单地用于表示数据,而无需进行任何编码:

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~最后,允许%字符本身进行百分比编码。

这只留下以下禁止出现在URL中的ASCII字符:

控制字符(chars0-1F和7F),包括新行、选项卡和回车。"<>^`{|}ASCII中的其他每个字符都可以合法地在URL中显示。

然后,RFC 3987用以下unicode字符范围扩展了这组非保留字符:

代码语言:javascript复制 %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的特定部分是合法的。例如,保留字符[和]作为http://[1080::8:800:200C:417A]/foo等URL中的IPv6文字主机的一部分是合法的,但在任何其他上下文中都是不合法的,因此OP的http://example.com/file[/].html示例是非法的。