HTTP基础:URL

前言

URL 在我们的开发过程中经常用到,很多情况下可能就知道它很表面的含义,接下来详细说说 URL 相关的知识点。

正题

在开始文章前,有几个问题需要思考一下:

  • URL 语法格式
  • URL 访问资源协议有哪些
  • URL 字符集

1. URL 语法格式

URL 提供了一种定位因特网上任意资源的手段,但这些资源时可以通过各种不同的方案(比如 HTTP、FTP、SMTP)来访问,因此 URL 语法会随方案的不同而有所不同。这是不是意味着每种不同的 URL 方案都会有完全不同的语法呢?实际上,不是的。大部分 URL 都遵循通用的 URL 语法,而且不同 URL 方案的风格和语法都有不少重叠。

大多数 URL 方案的 URL 语法都建立在这个有 9 部分构成的通用格式上:

<schema>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>

几乎没有那个 URL 中包含了所有这些组件。URL 最重要的 3 部分是方案(schema)、主机(host)和路径(path)

1.1 方案——使用什么协议

方案实际上是规定如何访问指定资源的主要标识符,它会告诉负责解析 URL 的应用程序应该使用什么协议。方案组件必须以一个字母符号开始,由第一个 “:”符号将其与 URL 的其余部分分隔开来。方案名是大小写无关的。

1.2 主机与端口

要想在因特网上找到资源,应用程序要知道是哪台机器装载了资源,以及在那台机器的什么地方可以找到能对目标资源进行访问的服务器。URL 的主机和㐰组件提供了这两组信息。

主机组件标识了因特网上能够访问资源的宿主机器。可以用上述主机名或者 IP 地址来表示主机名。

端口组件标识了服务器正在监听的网络端口。对下层使用了 TCP 协议的 HTTP 来说,默认端口号为 80。

1.3 用户名和密码

更有趣的组件是用户和密码组件,用户名和密码中间有冒号(:)分割。很多服务器都要求输入用户名和密码才会允许用户访问数据。FTP 服务器就是这样一个常见的实例。

1.4 路径

URL 的路径组件说明了资源位于服务器的什么地方。路径通常很像一个分级的文件系统路径。

1.5 参数

对很多方案来说,只有简单的主机名和到达对象的路径是不够的。除了服务器正在监听的端口,以及是否能够通过用户名和密码访问资源外,很多协议都还需要更多的信息才能工作。负责解析 URL 的应用程序需要这些协议参数来访问资源。否则,另一端的服务器就不会为请求提供服务,或者更糟糕的是,提供错误的服务。

为了向应用程序提供它们所需的输入参数,以便正确地与服务器进行交互,URL 中有一个参数组件。这个组件就是 URL 中的名值对列表,由符号“;”将其与 URL 的其余部分(以及各名值对)分割开来。它们为应用程序提供了访问资源所需的所有附加信息。

1.6 查询字符串

很多资源,比如数据库服务,都是可以通过提问题或进行查询来缩小所请求资源类型范围。按照常规,很多网关都希望查询字符串以一系列“名/值”对的形式出现,名值对之间用字符“&”分割。

1.7 片段

有些资源类型,比如 HTML,除了资源级之外,还可以做进一步的划分。比如,对一个带有章节的大型文本文档来说,资源的 URL 会指向整个文本文档,但理想的情况是,能够指定资源中的那些章节。

为了引用部分资源或资源的一个片段,URL 支持使用片段(frag)组件来表示一个资源内部的片段。比如,URL 可以指向 HTML 文档中一个特定的图片或小节。

HTTP 服务器通常只处理整个对象,而不是对象的片段,客户端不能将片段传送给服务器。浏览器从服务器获得了整个资源后,会根据片段来显示你感兴趣的那部分资源。

HTTP基础:URL

2. URL 访问资源协议有哪些

方案实际上是规定如何访问指定资源的主要标识符,它会告诉负责解析 URL 的应用程序应该使用什么协议。方案组件必须以一个字母符号开始,由第一个 “:”符号将其与 URL 的其余部分分隔开来。方案名是大小写无关的。常见的一下方案:

2.1 http

超文本传输协议方案,除了没有用户名和密码之外,与通用的 URL 格式相符,如果省略了端口,就默认为 80。

2.2 https

方案 https 与方案 http 是一对。唯一的区别在于方案 https 使用了网景的 SSL,SSL 为 HTTP 连接提供了端到端的加密机制。其语法与 HTTP 的语法相同,默认端口为 443。

2.3 mailto

Mailto URL 指向的是 E-mail 地址。由于 E-mail 的行为与其他方案都有所不同(它并不指向任何可以直接访问的对象),所以 mailto URL 的格式与标准 URL 的格式也有所不同。因特网 E-mail 地址的语法记录在 RFC 822 中。

基本格式:mailto:<RFC-822-add-spec>

示       例:mailto:[email protected]

2.4 ftp

文件传输协议 URL 可以用来从 FTP 服务器上下载或向其上传文件,并获取 FTP 服务器上的目录结构内容的列表。

2.5 rtsp rtspu

RTSP URL 是可以通过实时流传输协议(Real Time Streaming Protocol)解析的音/视频媒体资源的标识符。方案 rtspu 中的 u 表示它使用 UDP 协议来获取资源的。

2.6 file

方案 file 表示一台指定主机(通过本地磁盘、网络文件系统或其他一些文件共享系统)上可直接访问的文件。各字段上可以直接访问文件。各字段都遵循通用格式。如果省略了主机名,就默认为正在使用 URL 的本地主机。

2.7 news

根据 PFC 1036 的定义,方案 news 用来访问一些特定的文章或新闻组。它有一个很独特的性质:news URL 自身包含的信息不足以对资源进行定位。news URL 中缺乏到何处获取资源的信息——没有提供主机名或机器名称。从用户那里获取此类信息是解析程序的工作。比如,在网景浏览器的“选型”(Options)菜单中,就可以指定自己的 NNTP(news)服务器。这样,浏览器有了 news URL 的时候就知道应该使用哪个服务器了。

新闻资源可以从多台服务器中获得。它们被称为位置无关的,因为对它们的访问不依赖于任何一个源服务器。news URL 中保留了字符“@”,用来区分指向新闻组的 news URL 和指向特定新闻文章的 new URL。

基本格式:news:<newsgroup>、news:<news-article-id>

示       例:news:rec.arts.startrek

2.8 telnet

方案 Telnet 用于访问交互式业务。它表示的并不是对象自身,而是可通过 telnet  协议访问的交互式应用程序(资源)。

3. URL 字符集

URL 是可移植的(portable)。它要统一地命名因特网上所有的资源,这也就意味着要通过各种不同的协议来传送这些资源。这些协议在传输数据时使用不同的机制,所以,设计 URL 使其可以通过任意因特网协议安全传输是很重要的。

安全传输意味着 URL 的传输不能丢失信息。有些协议,比如传输电子邮件的简单邮件传输协议(Simple Mail Transfer Protocol,SMTP),所使用的传输方法就会剥去一些特定的字符。为了避开这些问题,URL 只能使用一些相对较小的、通用的安全字母表中的字符。

除了希望 URL 可以被所有因特网协议进行传送之外,设计者们还希望 URL 也可供人类阅读。因此,即使不可见、不可打印的字符能够穿过邮件程序,从而成为可移植的,也不能在 URL 中使用。

URL 还得是完整的,这就使问题变得更加复杂。URL 的设计者们认识到有时人们可能会希望 URL 中包含通用的安全字母表之外的二进制数据或字符。因此,需要有一种转义机制,能够将不安全的字符编码为安全字符,再进行传输。

默认的计算机系统字符集通常都倾向于以英语为中心。从历史上来看,很多计算机应用程序使用的都是 US-ASCII 字符集。US-ASCII 使用 7 位二进制码来表示英文打字机提供的大多数按键和少数用于文本格式和硬件通知的不可打印控制字符。

由于 US-ASCII 的历史悠久,所以其可移植性很好。但是,虽然美国用户使用起来很便捷,它却并不支持在各种欧洲语言或全世界数十亿人使用的数百种非罗马语言中很常见的变体字符。而且,有些 URL 中还会包含任意的二进制数据。认识到对完整性的需求之后,URL 的设计者就将转义序列集成了进去。通过转义序列,就可以用 US-ASCII 字符集的有限子集对任意字符值或数据进行编码了,这样就实现了可移植性和完整性。

3.1 编码机制

为了避开安全字符集表示法带来的限制,人们设计了一种编码机制,用来在 URL 中表示各种不安全的字符。这种编码机制就是通过一种“转义”表示法表示不安全字符的,这种转义法包含一个百分号(%),后面跟着两个表示字符 ASCII 码的十六进制数。

例如:http://www.joes-hardware.com/%7Ejoe(字符:~ ;ASCII 码:126[0x7E])

3.2 字符限制

在 URL 中,有几个字符被保留起来有着特殊的含义。有些字符不在定义的 US-ASCII 可打印字符集中。还有些字符会与某些因特网网关和协议产生混淆,因此不赞成使用。

下面列出了一些字符,在将其用于保留用途之外的场合时,要在 URL 中对其进行编码。

  • %:保留作为编码字符的转义标志
  •  /:保留作为路径组件中分隔路径段的定界符
  •  . :保留在路径组件中使用
  •  ..:保留在路径组件中使用
  • # :保留作为分段定界符使用
  • ?:保留作为查询字符串定界符使用
  • ;:保留作为参数定界符使用
  • ::保留作为方案、用户/口令,以及主机/端口组件的定界符使用
  • $ +:保留
  • @ & =:在某些方案的上下文中有特殊的含义,保留
  • {} | \ ^ ~ [] ':由于各种传输 Agent 代理,比如各种网关的不安全处理,使用受限
  • <> ":不安全;这些字符在 URL 范围之外通常是有意义的,比如在文档中对 URL 自身进行定界(比如 http://www.joes-hardware.com),所以应该对其进行编码
  • 0x00-0x1F,0x7F:受限,这些十六进制范围内的字符都在 US-ASCII 字符集的不可打印区间内
  • >0x7F:受限,十六进制值在此范围内的字符都不在 US-ASCII 字符集的 7 比特范围内