urllib.parse — 将 URL 解析为组件

源代码: Lib/urllib/parse.py


此模块定义了一个标准接口,用于将统一资源定位符 (URL) 字符串分解为组件(寻址方案、网络位置、路径等),将组件重新组合为 URL 字符串,以及在给定“基本 URL”的情况下将“相对 URL”转换为绝对 URL。

该模块的设计符合互联网关于相对统一资源定位符的 RFC。它支持以下 URL 方案:file, ftp, gopher, hdl, http, https, imap, itms-services, mailto, mms, news, nntp, prospero, rsync, rtsp, rtsps, rtspu, sftp, shttp, sip, sips, snews, svn, svn+ssh, telnet, wais, ws, wss

CPython 实现细节: 包含 itms-services URL 方案可能会阻止应用程序通过 Apple 的 macOS 和 iOS App Store 审核流程。在 iOS 上,始终会删除 itms-services 方案的处理;在 macOS 上,如果 CPython 是使用 --with-app-store-compliance 选项构建的,则可能会被删除。

urllib.parse 模块定义了两个主要类别的函数:URL 解析和 URL 引用。这些将在以下部分中详细介绍。

该模块的函数使用已弃用的术语 netloc (或 net_loc),该术语在 RFC 1808 中引入。但是,该术语已被 RFC 3986 废弃,后者引入了术语 authority 作为其替代。 为了向后兼容,继续使用 netloc

URL 解析

URL 解析函数侧重于将 URL 字符串拆分为其组件,或者将 URL 组件组合为 URL 字符串。

urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)

将 URL 解析为六个组件,返回一个包含 6 个项目的命名元组。 这对应于 URL 的通用结构:scheme://netloc/path;parameters?query#fragment。 每个元组项目都是一个字符串,可能为空。 这些组件不会被分解为更小的部分(例如,网络位置是单个字符串),并且不会展开 % 转义符。 上面显示的定界符不是结果的一部分,除了 path 组件中的前导斜杠(如果存在则保留)。 例如

>>> from urllib.parse import urlparse
>>> urlparse("scheme://netloc/path;parameters?query#fragment")
ParseResult(scheme='scheme', netloc='netloc', path='/path;parameters', params='',
            query='query', fragment='fragment')
>>> o = urlparse("https://docs.pythonlang.cn:80/3/library/urllib.parse.html?"
...              "highlight=params#url-parsing")
>>> o
ParseResult(scheme='http', netloc='docs.python.org:80',
            path='/3/library/urllib.parse.html', params='',
            query='highlight=params', fragment='url-parsing')
>>> o.scheme
'http'
>>> o.netloc
'docs.python.org:80'
>>> o.hostname
'docs.python.org'
>>> o.port
80
>>> o._replace(fragment="").geturl()
'https://docs.pythonlang.cn:80/3/library/urllib.parse.html?highlight=params'

按照 RFC 1808 中的语法规范,仅当 netloc 由“//”正确引入时,urlparse 才会识别 netloc。 否则,输入将被假定为相对 URL,因此以路径组件开头。

>>> from urllib.parse import urlparse
>>> urlparse('//www.cwi.nl:80/%7Eguido/Python.html')
ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')
>>> urlparse('www.cwi.nl/%7Eguido/Python.html')
ParseResult(scheme='', netloc='', path='www.cwi.nl/%7Eguido/Python.html',
            params='', query='', fragment='')
>>> urlparse('help/Python.html')
ParseResult(scheme='', netloc='', path='help/Python.html', params='',
            query='', fragment='')

scheme 参数给出默认的寻址方案,仅在 URL 未指定方案时使用。 它应该与 urlstring 具有相同的类型(文本或字节),但默认值 '' 始终是允许的,并且如果合适,会自动转换为 b''

如果 allow_fragments 参数为 false,则不会识别片段标识符。 相反,它们会被解析为路径、参数或查询组件的一部分,并且在返回值中,fragment 将设置为空字符串。

返回值是一个命名元组,这意味着它的项目可以通过索引访问,也可以作为命名属性访问,这些属性是

属性

索引

如果不存在则取值

scheme

0

URL 方案说明符

scheme 参数

netloc

1

网络位置部分

空字符串

path

2

分层路径

空字符串

params

3

最后一个路径元素的参数

空字符串

query

4

查询组件

空字符串

fragment

5

片段标识符

空字符串

username

用户名

None

password

密码

None

hostname

主机名(小写)

None

port

端口号(如果存在),为整数

None

如果在 URL 中指定了无效的端口,则读取 port 属性将引发 ValueError。 有关结果对象的更多信息,请参阅 结构化解析结果 部分。

netloc 属性中不匹配的方括号将引发 ValueError

在 NFKC 规范化(IDNA 编码使用)下分解为 /, ?, #, @: 中任何一个的 netloc 属性中的字符,将引发 ValueError。 如果在解析之前分解 URL,则不会引发错误。

与所有命名元组的情况一样,子类有一些特别有用的其他方法和属性。 其中一个方法是 _replace()_replace() 方法将返回一个新的 ParseResult 对象,将指定的字段替换为新值。

>>> from urllib.parse import urlparse
>>> u = urlparse('//www.cwi.nl:80/%7Eguido/Python.html')
>>> u
ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')
>>> u._replace(scheme='http')
ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')

警告

urlparse() 不执行验证。 有关详细信息,请参阅 URL 解析安全性

在 3.2 版本中更改: 添加了 IPv6 URL 解析功能。

3.3 版本更改: 现在,根据 RFC 3986,所有 URL 方案都会解析片段(除非 allow_fragments 为 false)。以前,存在一个支持片段的方案的允许列表。

3.6 版本更改: 超出范围的端口号现在会引发 ValueError,而不是返回 None

3.8 版本更改: 在 NFKC 规范化下影响 netloc 解析的字符现在会引发 ValueError

urllib.parse.parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&')

解析作为字符串参数给定的查询字符串(类型为 application/x-www-form-urlencoded 的数据)。数据以字典形式返回。字典的键是唯一的查询变量名称,值是每个名称的值的列表。

可选参数 keep_blank_values 是一个标志,指示是否应将百分比编码查询中的空白值视为空白字符串。真值表示应将空白保留为空白字符串。默认的 false 值表示应忽略空白值,并将其视为未包含。

可选参数 strict_parsing 是一个标志,指示如何处理解析错误。如果为 false(默认值),则会静默忽略错误。如果为 true,则错误会引发 ValueError 异常。

可选的 encodingerrors 参数指定如何将百分比编码的序列解码为 Unicode 字符,如 bytes.decode() 方法所接受的那样。

可选参数 max_num_fields 是要读取的最大字段数。如果设置了此参数,则如果读取的字段数超过 max_num_fields,则会引发 ValueError

可选参数 separator 是用于分隔查询参数的符号。默认为 &

使用 urllib.parse.urlencode() 函数(将 doseq 参数设置为 True)将此类字典转换为查询字符串。

3.2 版本更改: 添加了 encodingerrors 参数。

3.8 版本更改: 添加了 max_num_fields 参数。

3.10 版本更改: 添加了 separator 参数,默认值为 &。早于 Python 3.10 的 Python 版本允许同时使用 ;& 作为查询参数分隔符。这已更改为仅允许单个分隔符键,默认分隔符为 &

urllib.parse.parse_qsl(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&')

解析作为字符串参数给定的查询字符串(类型为 application/x-www-form-urlencoded 的数据)。数据以名称、值对列表的形式返回。

可选参数 keep_blank_values 是一个标志,指示是否应将百分比编码查询中的空白值视为空白字符串。真值表示应将空白保留为空白字符串。默认的 false 值表示应忽略空白值,并将其视为未包含。

可选参数 strict_parsing 是一个标志,指示如何处理解析错误。如果为 false(默认值),则会静默忽略错误。如果为 true,则错误会引发 ValueError 异常。

可选的 encodingerrors 参数指定如何将百分比编码的序列解码为 Unicode 字符,如 bytes.decode() 方法所接受的那样。

可选参数 max_num_fields 是要读取的最大字段数。如果设置了此参数,则如果读取的字段数超过 max_num_fields,则会引发 ValueError

可选参数 separator 是用于分隔查询参数的符号。默认为 &

使用 urllib.parse.urlencode() 函数将此类对列表转换为查询字符串。

3.2 版本更改: 添加了 encodingerrors 参数。

3.8 版本更改: 添加了 max_num_fields 参数。

3.10 版本更改: 添加了 separator 参数,默认值为 &。早于 Python 3.10 的 Python 版本允许同时使用 ;& 作为查询参数分隔符。这已更改为仅允许单个分隔符键,默认分隔符为 &

urllib.parse.urlunparse(parts)

urlparse() 返回的元组构造 URL。parts 参数可以是任何六项可迭代对象。如果最初解析的 URL 具有不必要的分隔符(例如,带有空查询的 ?;RFC 声明这些是等效的),则这可能会导致略有不同但等效的 URL。

urllib.parse.urlsplit(urlstring, scheme='', allow_fragments=True)

这类似于 urlparse(),但不从 URL 中拆分参数。如果想要使用更新的 URL 语法(允许将参数应用于 URL 的 path 部分的每个段)(请参阅 RFC 2396),则通常应使用此方法而不是 urlparse()。需要一个单独的函数来分隔路径段和参数。此函数返回一个 5 项 命名元组

(addressing scheme, network location, path, query, fragment identifier).

返回值是一个 命名元组,可以通过索引或命名属性访问其项。

属性

索引

如果不存在则取值

scheme

0

URL 方案说明符

scheme 参数

netloc

1

网络位置部分

空字符串

path

2

分层路径

空字符串

query

3

查询组件

空字符串

fragment

4

片段标识符

空字符串

username

用户名

None

password

密码

None

hostname

主机名(小写)

None

port

端口号(如果存在),为整数

None

如果在 URL 中指定了无效的端口,则读取 port 属性将引发 ValueError。 有关结果对象的更多信息,请参阅 结构化解析结果 部分。

netloc 属性中不匹配的方括号将引发 ValueError

在 NFKC 规范化(IDNA 编码使用)下分解为 /, ?, #, @: 中任何一个的 netloc 属性中的字符,将引发 ValueError。 如果在解析之前分解 URL,则不会引发错误。

遵循更新 RFC 3986 的一些 WHATWG 规范,URL 中会删除前导 C0 控制字符和空格字符。\n\r 和制表符 \t 字符会从 URL 的任何位置删除。

警告

urlsplit() 不执行验证。有关详细信息,请参阅 URL 解析安全性

3.6 版本更改: 超出范围的端口号现在会引发 ValueError,而不是返回 None

3.8 版本更改: 在 NFKC 规范化下影响 netloc 解析的字符现在会引发 ValueError

3.10 版本更改: 从 URL 中删除了 ASCII 换行符和制表符。

3.12 版本更改: 从 URL 中删除了前导 WHATWG C0 控制字符和空格字符。

urllib.parse.urlunsplit(parts)

urlsplit() 返回的元组元素组合成一个完整的 URL 字符串。parts 参数可以是任何五项可迭代对象。如果最初解析的 URL 具有不必要的分隔符(例如,带有空查询的 ?;RFC 声明这些是等效的),则这可能会导致略有不同但等效的 URL。

urllib.parse.urljoin(base, url, allow_fragments=True)

通过将“基本 URL”(base)与另一个 URL(url)组合,构造一个完整的(“绝对”)URL。简单来说,它使用基本 URL 的组件,特别是寻址方案、网络位置和(部分)路径,来提供相对 URL 中缺失的组件。例如:

>>> from urllib.parse import urljoin
>>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
'http://www.cwi.nl/%7Eguido/FAQ.html'

allow_fragments 参数的含义和默认值与 urlparse() 相同。

注意

如果 url 是一个绝对 URL(即,它以 //scheme:// 开头),则 url 的主机名和/或方案将出现在结果中。例如:

>>> urljoin('http://www.cwi.nl/%7Eguido/Python.html',
...         '//pythonlang.cn/%7Eguido')
'https://pythonlang.cn/%7Eguido'

如果您不希望出现这种行为,请使用 urlsplit()urlunsplit()url 进行预处理,删除可能的 schemenetloc 部分。

警告

由于可以将绝对 URL 作为 url 参数传递,因此将 urljoin 与攻击者控制的 url 一起使用通常是不安全的。例如,在 urljoin("https://website.com/users/", username) 中,如果 username 可以包含绝对 URL,则 urljoin 的结果将是绝对 URL。

在 3.5 版本中更改: 行为已更新,以匹配 RFC 3986 中定义的语义。

urllib.parse.urldefrag(url)

如果 url 包含片段标识符,则返回一个修改后的 url 版本,其中不包含片段标识符,并将片段标识符作为单独的字符串返回。如果 url 中没有片段标识符,则返回未修改的 url 和一个空字符串。

返回值是一个 命名元组,可以通过索引或命名属性访问其项。

属性

索引

如果不存在则取值

url

0

没有片段的 URL

空字符串

fragment

1

片段标识符

空字符串

有关结果对象的更多信息,请参阅 结构化解析结果 部分。

在 3.2 版本中更改: 结果是一个结构化对象,而不是一个简单的 2 元组。

urllib.parse.unwrap(url)

从包装的 URL 中提取 URL(即,格式为 <URL:scheme://host/path><scheme://host/path>URL:scheme://host/pathscheme://host/path 的字符串)。如果 url 不是包装的 URL,则它将按原样返回。

URL 解析安全性

urlsplit()urlparse() API 不执行输入的验证。它们可能不会对其他应用程序认为无效的输入引发错误。它们也可能在某些在其他地方可能不被视为 URL 的输入上成功。它们的目的是为了实际功能而不是纯粹性。

它们可能不会在异常输入上引发异常,而是可能返回一些作为空字符串的组件部分。或者组件可能包含比它们应该包含的更多内容。

我们建议这些 API 的用户,如果值可能在任何具有安全隐患的地方使用,应进行防御性编码。在信任返回的组件部分之前,请在您的代码中进行一些验证。那个 scheme 有意义吗?那是一个合理的 path 吗?那个 hostname 有什么奇怪的地方吗?等等。

构成 URL 的内容并非普遍明确定义。不同的应用程序有不同的需求和期望的约束。例如,正在进行的 WHATWG 规范 描述了面向用户的 Web 客户端(如 Web 浏览器)的需求。而 RFC 3986 则更通用。这些函数结合了两者的某些方面,但不能声称符合任何一个标准。由于 API 和现有用户代码对特定行为的期望都早于这两个标准,因此我们对更改 API 行为非常谨慎。

解析 ASCII 编码字节

URL 解析函数最初设计为仅对字符串进行操作。在实践中,能够将正确引用和编码的 URL 作为 ASCII 字节序列进行操作非常有用。因此,此模块中的 URL 解析函数都可以在 bytesbytearray 对象以及 str 对象上运行。

如果传入 str 数据,则结果也将仅包含 str 数据。如果传入 bytesbytearray 数据,则结果将仅包含 bytes 数据。

尝试在单个函数调用中将 str 数据与 bytesbytearray 混合,将导致引发 TypeError,而尝试传入非 ASCII 字节值将触发 UnicodeDecodeError

为了支持在 strbytes 之间更容易地转换结果对象,URL 解析函数的所有返回值都提供一个 encode() 方法(当结果包含 str 数据时)或一个 decode() 方法(当结果包含 bytes 数据时)。这些方法的签名与相应的 strbytes 方法的签名匹配(除了默认编码为 'ascii' 而不是 'utf-8')。每个方法都生成一个相应类型的值,该值包含 bytes 数据(对于 encode() 方法)或 str 数据(对于 decode() 方法)。

需要在可能包含非 ASCII 数据的、可能不正确引用的 URL 上操作的应用程序,需要在调用 URL 解析方法之前,自行将字节解码为字符。

本节中描述的行为仅适用于 URL 解析函数。URL 引用函数在生成或使用字节序列时使用自己的规则,如各个 URL 引用函数的文档中所详述。

在 3.2 版本中更改: URL 解析函数现在接受 ASCII 编码的字节序列

结构化解析结果

来自 urlparse()urlsplit()urldefrag() 函数的结果对象是 tuple 类型的子类。这些子类添加了这些函数的文档中列出的属性、上一节中描述的编码和解码支持,以及一个附加方法

urllib.parse.SplitResult.geturl()

以字符串形式返回原始 URL 的重新组合版本。这可能与原始 URL 不同,因为方案可能会被规范化为小写,并且空组件可能会被删除。具体来说,空的参数、查询和片段标识符将被删除。

对于 urldefrag() 的结果,只会移除空的片段标识符。对于 urlsplit()urlparse() 的结果,所有已记录的更改都会应用于此方法返回的 URL。

如果将此方法的结果传回原始解析函数,则结果保持不变。

>>> from urllib.parse import urlsplit
>>> url = 'HTTP://www.Python.org/doc/#'
>>> r1 = urlsplit(url)
>>> r1.geturl()
'http://www.Python.org/doc/'
>>> r2 = urlsplit(r1.geturl())
>>> r2.geturl()
'http://www.Python.org/doc/'

以下类提供了对 str 对象进行操作时结构化解析结果的实现。

class urllib.parse.DefragResult(url, fragment)

包含 str 数据的 urldefrag() 结果的具体类。encode() 方法返回一个 DefragResultBytes 实例。

在 3.2 版本中加入。

class urllib.parse.ParseResult(scheme, netloc, path, params, query, fragment)

包含 str 数据的 urlparse() 结果的具体类。encode() 方法返回一个 ParseResultBytes 实例。

class urllib.parse.SplitResult(scheme, netloc, path, query, fragment)

包含 str 数据的 urlsplit() 结果的具体类。encode() 方法返回一个 SplitResultBytes 实例。

以下类提供了对 bytesbytearray 对象进行操作时解析结果的实现。

class urllib.parse.DefragResultBytes(url, fragment)

包含 bytes 数据的 urldefrag() 结果的具体类。decode() 方法返回一个 DefragResult 实例。

在 3.2 版本中加入。

class urllib.parse.ParseResultBytes(scheme, netloc, path, params, query, fragment)

包含 bytes 数据的 urlparse() 结果的具体类。decode() 方法返回一个 ParseResult 实例。

在 3.2 版本中加入。

class urllib.parse.SplitResultBytes(scheme, netloc, path, query, fragment)

包含 bytes 数据的 urlsplit() 结果的具体类。decode() 方法返回一个 SplitResult 实例。

在 3.2 版本中加入。

URL 引用

URL 引用函数专注于获取程序数据,并通过引用特殊字符和适当编码非 ASCII 文本使其安全地用作 URL 组件。它们还支持反转这些操作,如果上述 URL 解析函数尚未涵盖该任务,则从 URL 组件的内容重新创建原始数据。

urllib.parse.quote(string, safe='/', encoding=None, errors=None)

使用 %xx 转义符替换 *string* 中的特殊字符。字母、数字和字符 '_.-~' 永远不会被引用。默认情况下,此函数旨在引用 URL 的路径部分。可选的 *safe* 参数指定不应被引用的其他 ASCII 字符——其默认值为 '/'

*string* 可以是 strbytes 对象。

在 3.7 版本中更改: RFC 2396 移动到 RFC 3986 以引用 URL 字符串。“~”现在包含在未保留字符集中。

可选的 *encoding* 和 *errors* 参数指定如何处理非 ASCII 字符,如 str.encode() 方法所接受的。*encoding* 默认为 'utf-8'。*errors* 默认为 'strict',这意味着不支持的字符会引发 UnicodeEncodeError。如果 *string* 是 bytes,则不得提供 *encoding* 和 *errors* ,否则会引发 TypeError

请注意,quote(string, safe, encoding, errors) 等效于 quote_from_bytes(string.encode(encoding, errors), safe)

示例:quote('/El Niño/') 产生 '/El%20Ni%C3%B1o/'

urllib.parse.quote_plus(string, safe='', encoding=None, errors=None)

quote() 类似,但也用加号替换空格,这是在构建要放入 URL 的查询字符串时引用 HTML 表单值所必需的。除非包含在 *safe* 中,否则原始字符串中的加号会被转义。它也不将 *safe* 默认为 '/'

示例:quote_plus('/El Niño/') 产生 '%2FEl+Ni%C3%B1o%2F'

urllib.parse.quote_from_bytes(bytes, safe='/')

类似于 quote(),但接受的是 bytes 对象而不是 str 对象,并且不执行字符串到字节的编码。

示例:quote_from_bytes(b'a&\xef') 产生 'a%26%EF'

urllib.parse.unquote(string, encoding='utf-8', errors='replace')

%xx 转义符替换为其对应的单字符。可选的 encodingerrors 参数指定如何将百分号编码的序列解码为 Unicode 字符,这与 bytes.decode() 方法接受的方式相同。

*string* 可以是 strbytes 对象。

encoding 默认为 'utf-8'errors 默认为 'replace',这意味着无效的序列会被替换为占位符字符。

示例:unquote('/El%20Ni%C3%B1o/') 产生 '/El Niño/'

在 3.9 版本中变更: string 参数支持字节和字符串对象(之前只支持字符串)。

urllib.parse.unquote_plus(string, encoding='utf-8', errors='replace')

类似于 unquote(),但也会将加号替换为空格,这是为了解码 HTML 表单值所必需的。

string 必须是 str

示例:unquote_plus('/El+Ni%C3%B1o/') 产生 '/El Niño/'

urllib.parse.unquote_to_bytes(string)

%xx 转义符替换为其对应的单字节等效项,并返回一个 bytes 对象。

*string* 可以是 strbytes 对象。

如果它是 str,则 string 中未转义的非 ASCII 字符会被编码为 UTF-8 字节。

示例:unquote_to_bytes('a%26%EF') 产生 b'a&\xef'

urllib.parse.urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus)

将映射对象或包含 strbytes 对象的二元组序列转换为百分号编码的 ASCII 文本字符串。如果生成的字符串要用作 urlopen() 函数进行 POST 操作的 *data*,则应将其编码为字节,否则会导致 TypeError

生成的字符串是一系列以 '&' 字符分隔的 key=value 对,其中 *key* 和 *value* 都使用 quote_via 函数进行引用。默认情况下,quote_plus() 用于引用值,这意味着空格被引用为 '+' 字符,而 '/' 字符被编码为 %2F,这符合 GET 请求的标准 (application/x-www-form-urlencoded)。可以作为 quote_via 传递的替代函数是 quote(),它会将空格编码为 %20 并且不编码 '/' 字符。为了最大程度地控制引用的内容,请使用 quote 并为 safe 指定一个值。

当使用二元组序列作为 query 参数时,每个元组的第一个元素是键,第二个元素是值。值元素本身可以是序列,在这种情况下,如果可选参数 doseq 的值为 True,则会为该键的值序列的每个元素生成以 '&' 分隔的各个 key=value 对。编码字符串中的参数顺序将与序列中参数元组的顺序匹配。

safeencodingerrors 参数将传递给 quote_via(仅当查询元素是 str 时才传递 encodingerrors 参数)。

要反转此编码过程,本模块提供了 parse_qs()parse_qsl(),用于将查询字符串解析为 Python 数据结构。

请参阅 urllib 示例,了解如何使用 urllib.parse.urlencode() 方法生成 URL 的查询字符串或 POST 请求的数据。

在 3.2 版本中变更: query 支持字节和字符串对象。

在 3.5 版本中变更: 添加了 quote_via 参数。

参见

WHATWG - URL Living standard

URL 标准的工作组,该标准定义了 URL、域名、IP 地址、application/x-www-form-urlencoded 格式及其 API。

RFC 3986 - 统一资源标识符

这是当前标准 (STD66)。对 urllib.parse 模块的任何更改都应符合此标准。可以观察到某些偏差,这些偏差主要是为了向后兼容性以及主要浏览器中常见的一些事实上的解析要求。

RFC 2732 - URL 中文字 IPv6 地址的格式。

这指定了 IPv6 URL 的解析要求。

RFC 2396 - 统一资源标识符(URI):通用语法

本文档描述了统一资源名称 (URN) 和统一资源定位符 (URL) 的通用语法要求。

RFC 2368 - mailto URL 方案。

mailto URL 方案的解析要求。

RFC 1808 - 相对统一资源定位符

此请求注释 (Request For Comments) 包括连接绝对 URL 和相对 URL 的规则,包括相当多的“异常示例”,这些示例控制着边界情况的处理。

RFC 1738 - 统一资源定位符 (URL)

此规范定义了绝对 URL 的正式语法和语义。