2.1 浏览因特网资源
获取 URL http://www.joes-hardware.com/seasonal/index-fall.html。那么 URL 分以下三部分。URL 的第一部分(http)是
- URL 方案(scheme)。方案可以告知 Web 客户端怎样访问资源。在这个例子中,URL 说明要使用 HTTP 协议。
- URL 的第二部分(www.joes-hardware.com)指的是服务器的位置。这部分告知Web 客户端资源位于何处。
- URL 的第三部分(/seasonal/index-fall.html)是资源路径。路径说明了请求的是服务器上哪个特定的本地资源。
URL 可以通过 HTTP 之外的其他协议来访问资源。它们可以指向因特网上的任意资源,或者个人的 E-mail 账户:
mailto:president@whitehouse.gov
或者通过其他协议(比如 FTP 协议)访问的各种文件:
ftp://ftp.lots-o-books.com/pub/complete-price-list.xls
或者从流视频服务器上下载电影:
rtsp://www.joes-hardware.com:554/interview/cto_video
URL 提供了一种统一的资源命名方式。大多数 URL 都有同样的:“方案 :// 服务器位置 / 路径”结构。因此,对网络上的每个资源以及获取这些资源的每种方式来说,命名资源的方法都只有一种,这样不管是谁都可以用名字来找到这个资源了。
2.2 URL的语法
大多数 URL 方案的 URL 语法都建立在这个由 9 部分构成的通用格式上:
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
几乎没有哪个 URL 中包含了所有这些组件。URL 最重要的 3 个部分是方案(scheme)、主机(host)和路径(path)。
通用URL组件
组 件 | 描 述 | 默 认 值 |
---|---|---|
方案 | 访问服务器以获取资源时要使用哪种协议 | 无 |
用户 | 某些方案访问资源时需要的用户名 | 匿名 |
密码 | 用户名后面可能要包含的密码,中间由冒号(:)分隔 | <E-mail 地址 > |
主机 | 资源宿主服务器的主机名或点分 IP 地址 | 无 |
端口 | 资源宿主服务器正在监听的端口号。很多方案都有默认端口号(HTTP 的默认端口号为 80) | 每个方案特有 |
路径 | 服务器上资源的本地名,由一个斜杠(/)将其与前面的URL 组件分隔开来。路径组件的语法是与服务器和方案有关的 | 无 |
参数 | 某些方案会用这个组件来指定输入参数。参数为名 / 值对。URL 中可以包含多个参数字段,它们相互之间以及与路径的其余部分之间用分号(;)分隔 | 无 |
查询 | 某些方案会用这个组件传递参数以激活应用程序(比如数据库、公告板、搜索引擎以及其他因特网网关)。查询组件的内容没有通用格式。用字符“?”将其与 URL 的其余 | |
部分分隔开来 | 无 | |
片段 | 一小片或一部分资源的名字。引用对象时,不会将 frag 字段传送给服务器;这个字段是在客户端内部使用的。通过字符“#”将其与 URL 的其余部分分隔开来 | 无 |
2.2.1 方案——使用什么协议
方案实际上是规定如何访问指定资源的主要标识符,它会告诉负责解析 URL 的应用程序应该使用什么协议。在我们这个简单的 HTTP URL 中所使用的方案就是 http。方案组件必须以一个字母符号开始,由第一个“:”符号将其与 URL 的其余部分分隔开来。方案名是大小写无关的,因此 URL“http://www.joes-hardware.com”和“HTTP://www.joes-hardware.com”是等价的。
2.2.2 主机与端口
端口组件标识了服务器正在监听的网络端口。对下层使用了 TCP 协议的 HTTP 来说,默认端口号为 80。
2.2.3 用户名和密码
很多服务器都要求输入用户名和密码才会允许用户访问数据。FTP 服务器就是这样一个常见的实例。这里有几个例子:
ftp://ftp.prep.ai.mit.edu/pub/gnu
ftp://anonymous@ftp.prep.ai.mit.edu/pub/gnu
ftp://anonymous:my_passwd@ftp.prep.ai.mit.edu/pub/gnu
http://joe:joespasswd@www.joes-hardware.com/sales_info.txt
第一个例子没有用户或密码组件,只有标准的方案、主机和路径。如果某应用程序使用的 URL 方案要求输入用户名和密码,比如 FTP,但用户没有提供,它通常会插入一个默认的用户名和密码。比如,如果向浏览器提供一个 FTP URL,但没有指定用户名和密码,它就会插入 anonymous(匿名用户)作为你的用户名,并发送一个默认的密码(Internet Explorer 会发送 IEUser,Netscape Navigator 则会发送mozilla)。
第二个例子显示了一个指定为 anonymous 的用户名。这个用户名与主机组件组合在一起,看起来就像 E-mail 地址一样。字符“@”将用户和密码组件与 URL 的其余部分分隔开来。
在第三个例子中,指定了用户名(anonymous)和密码(my_passwd),两者之间由
字符“:”分隔。
2.2.4 路径
URL 的路径组件说明了资源位于服务器的什么地方。路径通常很像一个分级的文件系统路径。比如:
http://www.joes-hardware.com:80/seasonal/index-fall.html
这个 URL 中的路径为 /seasonal/index-fall.html,很像 UNIX 文件系统中的文件系统路径。路径是服务器定位资源时所需的信息。 2 可以用字符“/”将 HTTP URL 的路径组件划分成一些路径段(path segment)(还是与 UNIX 文件系统中的文件路径类似)。每个路径段都有自己的参数(param)组件。
2.2.5 参数
对很多方案来说,只有简单的主机名和到达对象的路径是不够的。除了服务器正在监听的端口,以及是否能够通过用户名和密码访问资源外,很多协议都还需要更多的信息才能工作。
为了向应用程序提供它们所需的输入参数,以便正确地与服务器进行交互,URL 中有一个参数组件。这个组件就是 URL 中的名值对列表,由字符“;”将其与 URL 的其余部分(以及各名值对)分隔开来。它们为应用程序提供了访问资源所需的所有附加信息。比如:
ftp://prep.ai.mit.edu/pub/gnu;type=d
在这个例子中,有一个参数 type =d,参数名为 type,值为 d。
如前所述,HTTP URL 的路径组件可以分成若干路径段。每段都可以有自己的参数。比如:
http://www.joes-hardware.com/hammers;sale=false/index.html;graphics=true
这个例子就有两个路径段,hammers 和 index.html。hammers 路径段有参数 sale,其值
为 false。index.html 段有参数 graphics,其值为 true。
2.2.6 查询字符串
这个 URL 的大部分都与我们见过的其他 URL 类似。只有问号(?)右边的内容是新出现的。这部分被称为查询(query)组件。URL 的查询组件和标识网关资源的URL 路径组件一起被发送给服务器。查询字符串以一系列“名 / 值”对的形式出现,名值对之间用字符“&”分隔:
http://www.joes-hardware.com/inventory-check.cgi?item=12731&color=blue
在这个例子中,查询组件有两个名 / 值对:item=12731 和 color=blue。
2.2.7 片段
有些资源类型,比如 HTML,除了资源级之外,还可以做进一步的划分。比如,对一个带有章节的大型文本文档来说,资源的 URL 会指向整个文本文档,但理想的情况是,能够指定资源中的那些章节。
为了引用部分资源或资源的一个片段,URL 支持使用片段(frag)组件来表示一个资源内部的片段。比如,URL 可以指向 HTML 文档中一个特定的图片或小节。
片段挂在 URL 的右手边,最前面有一个字符“#”。比如:
http://www.joes-hardware.com/tools.html#drills
在这个例子中,片段 drills 引用了 Joe 的五金商店 Web 服务器上页面 /tools.html 中的一
个部分。这部分的名字叫做 drills。
HTTP 服务器通常只处理整个对象, 而不是对象的片段,客户端不能将片段传送给服务器。浏览器从服务器获得了整个资源之后,会根据片段来显示你感兴趣的那部分资源。服务器处理的是整个对象,因此 URL 片段仅由客户端使用
2.3 解析相对URL
2.4 各种令人头疼的字符
URL 是可移植的(portable)。它要统一地命名因特网上所有的资源,这也就意味着要通过各种不同的协议来传送这些资源。这些协议在传输数据时都会使用不同的机制,所以,设计 URL,使其可以通过任意因特网协议安全地传输是很重要的。
安全传输意味着 URL 的传输不能丢失信息。有些协议,比如传输电子邮件的简单邮件传输协议(Simple Mail Transfer Protocol,SMTP),所使用的传输方法就会剥去一些特定的字符。 为了避开这些问题,URL 只能使用一些相对较小的、通用的安全字母表中的字符。
除了希望 URL 可以被所有因特网协议进行传送之外,设计者们还希望 URL 也可供人类阅读。因此,即使不可见、不可打印的字符能够穿过邮件程序,从而成为可移植的,也不能在 URL 中使用。
URL 还得是完整的,这就使问题变得更加复杂了。URL 的设计者们认识到有时人们可能会希望 URL 中包含除通用的安全字母表之外的二进制数据或字符。因此,需要有一种转义机制,能够将不安全的字符编码为安全字符,再进行传输。
2.4.1 URL字符集
默认的计算机系统字符集通常都倾向于以英语为中心。从历史上来看,很多计算机应用程序使用的都是 US-ASCII 字符集。US-ASCII 使用 7 位二进制码来表示英文打字机提供的大多数按键和少数用于文本格式和硬件通知的不可打印控制字符。
由于 US-ASCII 的历史悠久,所以其可移植性很好。但是,虽然美国用户使用起来很便捷,它却并不支持在各种欧洲语言或全世界数十亿人使用的数百种非罗马语言中很常见的变体字符。
而且,有些 URL 中还会包含任意的二进制数据。认识到对完整性的需求之后,URL的设计者就将转义序列集成了进去。通过转义序列,就可以用 US-ASCII 字符集的有限子集对任意字符值或数据进行编码了,这样就实现了可移植性和完整性。
2.4.2 编码机制
为了避开安全字符集表示法带来的限制,人们设计了一种编码机制,用来在 URL 中表示各种不安全的字符。这种编码机制就是通过一种“转义”表示法来表示不安全字符的,这种转义表示法包含一个百分号(%),后面跟着两个表示字符 ASCII 码的十六进制数。
2.4.3 字符限制
在 URL 中,有几个字符被保留起来,有着特殊的含义。有些字符不在定义的 US-ASCII 可打印字符集中。还有些字符会与某些因特网网关和协议产生混淆,因此不赞成使用。
字符 | 保留/受限 |
---|---|
% | 保留作为编码字符的转义标志 |
/ | 保留作为路径组件中分隔路径段的定界符 |
. | 保留在路径组件中使用 |
.. | 保留在路径组件中使用 |
# | 保留作为分段定界符使用 |
? | 保留作为查询字符串定界符使用 |
; | 保留作为参数定界符使用 |
: | 保留作为方案、用户 / 口令,以及主机 / 端口组件的定界符使用 |
$,+ | 保留 |
@&= | 在某些方案的上下文中有特殊的含义,保留 |
{}|\^~[]` | 由于各种传输 Agent 代理,比如各种网关的不安全处理,使用受限 |
<>" | 不安全;这些字符在 URL 范围之外通常是有意义的,比如在文档中对 URL 自身进行定界(比如 http://www.joes-hardware.com),所以应该对其进行编码 |
0x00-0x1F, 0x7F | 受限,这些十六进制范围内的字符都在 US-ASCII 字符集的不可打印区间内 |
>0x7F | 受限,十六进制值在此范围内的字符都不在 US-ASCII 字符集的 7 比特范围内 |