揭开 URI、URL 和 URN 的面纱
本指南概述了 URI、URL 和 URN,解释了它们之间的区别和使用场景。
在开发网络应用时,我们经常需要调用不同的网络服务。在配置不同网络服务的通信和连接时,我们常常会遇到 URI、URL 和 URN 这些概念。通常,用户会难以区分它们,从而导致混淆或误用。在本文中,我们将通过举例并解释它们之间的区别,帮助大家更好地理解这些概念,并在阅读技术博客、文档或与其他工程师交流时正确地解读和使用它们。
什么是 URL?
URL (统一资源定位符) 提供了互联网上资源的网络地址或位置。它通常用于指定网页、文件或服务的位置。URL 为访问网络资源提供了统一的格式。它是网络浏览、链接以及互联网通信的关键组成部分。
URL 由多个部分组成,这些部分共同定义资源的地址和访问它所使用的协议。让我们解析下面的 URL 作为示例,并逐一解释每个部分的功能。
-
方案 (Scheme): 这指定了访问资源所使用的协议,比如 HTTP (超文本传输协议)、HTTPS (超文本传输协议安全版)、FTP (文件传输协议) 或者其他。
在此 URL 中的方案是
https
。 -
主机 (Host): 主机指定了托管资源的服务器的域名或 IP 地址。
在此 URL 中的主机是
example.logto.io
。 -
端口 (Port): (可选) 端口表示访问资源时在主机上使用的特定端口号。如果未指定端口,它将默认使用方案的标准端口。
HTTP 的默认端口是 80,而 HTTPS 的默认端口是 443。
在此 URL 中 的端口是
8080
。 -
路径 (Path): (可选) 路径指示资源在服务器上的具体位置或目录,可以包含目录和文件名。
在此 URL 中的路径应为
/blogs/index.html
。 -
查询参数 (Query Parameters): (可选) 查询参数是传递给资源的附加参数,通常用于动态网络应用。它们出现在路径之后,并以
?
符号分隔。在此 URL 中的查询参数是
params1=value1¶m2=value2
,通常以键值对的形式表示,多个键值对之间由&
符号分隔。在实际使用场景中,通常需要进行编码以避免空格等字符。 -
片段标识符 (Fragment Identifier): (可选) 它也可以称为锚点,用于定位资源中的特定位置。
在此 URL 中的锚点是
#introduction
。
另外,举例来说,使用文件服务或网页上的许多“联系我们”按钮,都链接到 URL,例如:
ftp://documents.logto.io/files/legal/soc_ii.pdf
mailto:[email protected]?subject=Enterprise%20quota%20request
什么是 URI?
URI 是“统一资源标识符”的简称。它是一串字符,用于标识特定资源,例如网页、文件或服务。URI 提供了一种使用标准化格式来唯一标识和定位资源的方法。
URI 主要由两个组成部分构成:
- 方案: 指示访问资源所使用的协议或方案。
- 资源标识符 (Resource Identifier): 标识被访问或引用的具体资源。资源标识符的格式取决于所使用的方案。
从语法角度来看,URI 大多数情况下遵循与 URL 相同的格式,如 RFC 3986 中所规定。
尽管这种 URI 的格式类似于 URL,但是它并不保证能够访问网络上的任何资源。使用这种格式可以减少名称空间名称冲突的情况。
在以上部分中,我们介绍了 URL,它不仅标识资源,还帮助定位该资源。因此,实际上 URL 是 URI 的一个真子集。
什么是 URN?
URN 可能不像 URL 和 URI 那么常见。它代表“统一资源名称”,其作用范围是以持久的方式标识资源,即使此类资源不再存在。
与 URL 不同,URN 并不提供任何关于如何定位资源的信息,它仅仅是标识资源,就像一个纯粹的 URI 一样。具体而言,URN 是一种采用 "urn" 方案的 URI,具有以下结构,如 RFC 2141 所描述:
<URN>:<NID>:<NSS>
- URN: 通常是
urn
。 - 名称空间标识符 (Namespace Identifier, NID): 表示定义和管理 URN 的唯一名称空间或标识符系统。它提供上下文并确保标识符的唯一性。例如,名称空间包括 ISBN (国际标准书号) 等。
- 名称空间特定字符串 (Namespace Specific String, NSS): 它是一个字符串,用于在指定的名称空间中唯一地标识资源。标识符本身并不传达任何关于资源位置或访问方法的信息。
例如,一本非常著名的计算机系统入门书籍 CSAPP 的 ISBN 号可以表示为 URN urn:isbn:9780134092669
。
URNs 通常用于各种标准协议中,比如 SAML 协议中的断言,其对应的 URN 是 urn:oasis:names:tc:SAML:2.0:assertion
。
在软件工程中,我们也可以根据 URN 命名规则在我们自己的系统中定义特定用途的 URN。例如在 Logto 中,为了启用 Organization,你需要在使用 SDK 时在配置中添加 urn:logto:scope:organizations
范围 (scope)。每个 Organization 也都有自己专用的 URN urn:logto:organization:{orgId}
。
结论
下面的维恩图可以帮助说明 URI、URL 和 URN 之间的关系:
URI、URL 和 URN 都可以用来标识不同的资源,但只有 URL 可以精确定位资源的位置。
URI 和 URL 可以支持多种方案,比如 HTTP、HTTPS、FTP,但 URN 可以视为只支持 urn
方案。
所有的 URL 或 URN 都是 URI,但并非所有的 URI 都是 URL 或 URN。