http权威指南第二章

url与资源

本章我们将介绍以下内容:

  • url语法,以及各种url组件的含义及其所做的工作;
  • 很多web客户端都支持url的快捷方式,包括相对url和自动扩展url;
  • url编码和字符规则;
  • 支持各种因特网信息系统的常见url方案;
  • url的未来,包括urn-这种框架可以在对象从一处搬移到另一处时,保持稳定的访问名称。

2.1浏览因特网资源

url是浏览器寻找信息时所需要的资源位置。通过url人类和应用程序才能找到并共享因特网上大量的数据资源。url是人们对http和其它协议的常用访问点;一个人将浏览器指向一个url,浏览器会在幕后发送适当的协议报文来获取人们所期望的资源。

  • url的第一部分称为方案(scheme)说明了资源所使用的协议,例如http协议。
  • 第二部分是服务器的因特网地址,例如www.baidu.com
  • 其余部分指定了web服务器上的某个资源。例如/index.html

这一部分在第一章已经说过,在这里重复一下。

2.2url的语法

url提供了一种定位网上任意资源的手段,这些资源可以通过不同的方案(http,ftp,smtp)来访问,因此,url语法会随方案的不同而有所不同。

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

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

组件 描述
方案 访问服务器以获取资源时要使用那种协议
用户 某些方案访问资源时需要的用户名
密码 用户名后面可能要包含的密码中间由冒号分隔
主机 资源宿主服务器的主机名或点分ip地址
端口 宿主服务器正在监听的端口,很多方案都有默认端口号
路径 服务器上的资源的本地名,由一个斜杠与前面的url分隔开,路径组件的语法与服务器和方案有关
参数 某些方案会用到这个组件来指定输入参数,参数为名/值对。url中可以包含多个参数字段,他们互相之间以及与路径的其余部分用分号分隔
查询 某些方案会用到这个组件传递参数以激活应用程序。查询组件的内容没有通用格式。用字符?将其与url的其它部分分隔开
片段 一小片或一部分资源的名字。引用对象时,不会将frag字段传递给服务器,这个字段是客户端内部使用的,通过字符#将其与其它部分分隔开

2.2.1方案-使用什么协议

方案是规定如何访问指定资源的主要标识符,它会告诉负责解析url的应用程序应该使用什么协议。

方案组件必须以一个字母符号开头,由第一个:将其与其余部分分隔开。方案名与大小写无关。

2.2.2主机与端口

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

主机组件标识了因特网上能够访问资源的宿主机器。端口组件标识了服务器正在监听的网络端口

2.2.3用户名和密码

更有趣的是用户名和密码组件,不少服务器要求输入用户名和密码才允许访问数据,例如一个典型的ftp服务器。

2.2.4路径

url的路径组件说明了资源位于服务器的什么地方。路径通常像一个分级的文件系统路径。例如用/将http url的路径附件分成一些路径段(path segment)每个路径段都有自己的参数组件

2.2.5参数

负责解析url的应用程序需要这些协议参数来访问资源。否则另一端的服务器可能就不会为请求提供服务,或者提供错误的服务

2.2.6查询字符串

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

2.2.7片段

有些资源类型,除了资源级之外,还可以做进一步的划分。为了引用部分资源或资源的一个片段,url支持使用片段(frag)表示一个资源内部的片段

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

2.3url快捷方式

web客户端可以理解并使用几种url快捷方式。相对url是在某资源内部指定一个资源的边界缩略方式。很多浏览器还支持url的自动扩展,也就是用户键入一个关键部分,然后由浏览器将其余部分填充起来

2.3.1相对url

url有两种方式:绝对的和相对的。到目前为止,我们只见过绝对url中包含访问得全部信息

另一方面,相对url是不完整的要从相对url中获取访问全部信息,就必须相对于另一个,被称为其基础的url进行解析。

相对url是url的一种便捷记法。如果你手工写过html的话,可能就会发现相对url是多么便捷。

1.基础url
转换处理的第一步就是找到基础url。基础url是作为相对url的参考点使用可以来自以下几个地方。

  • 在资源中现实提供
    有些资源会显式的指定基础url。比如html文档中可能会包含一个定义了基础url的html标记<base>通过他来转换那个html文档中的所有相对url
  • 封装资源的基础url
    如果在一个没有显示指定基础url的资源中发现一个相对url
  • 没有基础url在某些情况下没有基础url这通常意味着你有一个相对url,但有时可能只是是个不完整或损坏了的url。

2.解析相对引用

前面我们介绍了url的基本组件和语法。要将相对url转换为一个绝对url下一步要做的就是将相对url和基础url花分成组件段。

实际上,这样只是在解析url,但这种做法会将其划分一个个组件因此通常会称作分解(decomposing)url.只要将基础和相对url划分成了组件就可以应用算法来转换了。

2.3.2自动扩展url

有些浏览器会在用户提交url之后,或者在用户输入的时候尝试这自动扩展url。这就为用户提供了一条捷径:用户不需要输入完整的url,因为浏览器会自动扩展。

这些自动扩展特性有以下两种方式。

  • 主机名扩展
    在主机名扩展中,只要有些小提示,浏览器就可以在没有帮助的情况下,将你输入的主机名扩展为完整的主机名。

  • 历史扩展
    浏览器用来节省用户输入url时间的另一种技巧是,将用户访问过的url历史存储起来,当你输入url时,他们就可以将你输入的ulr与历史url前缀进行匹配,并提供一些完整的选项供你选择。

2.4令人头疼的字符

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

安全传输意味着url传输不能丢失信息。有些协议,所使用的传输方法就会剥去一些特定的字符。为了避开这些问题,url只能使用一些相对较小的通用的安全字母表中的字符。

除了希望url刻意被所有因特网协议进行传送外,设计者还希望url是可读的。因此即使不可见,不可打印的字符能够穿过邮件协议,从而称为可移植的,也不能在url中使用。

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

2.4.1url字符集

默认的计算机系统字符集通常都倾向于以英语为中心。从历史上来看,很多计算机程序使用的都是us-ascll字符集。

由于ascll的历史悠久,所以可移植性很好。但是,它不支持在其他地方使用。

而且,有些url中还会包含二进制数据。认识到对完整性的需求之后,url的设计者就将转义序列集成进去了,通过转义序列,就可以用ascll字符集的有限子集对任意字符之或数据进行编码了,这样就实现了可移植性和完整性。

2.4.2编码机制

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

2.4.3字符限制

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

字符 保留/受限
% 保留作为编码字符的转义标志
/ 保留作为路径组件分隔路径段的定界符
. 保留在路径组件中使用
.. 保留在路径组件中使用
# 保留作为分段定界符使用
? 保留作为查询字段定界符使用
; 保留作为参数定界符使用
: 保留作为方案、用户/口令、以及主机/端口组件的定界符使用
$,+ 保留
@$= 在某些方案上下文中有特殊含义,保留
{}^~[]' 由于各种方案上下文中有特殊含义,保留
<>" 不安全:这些字符在url范围之外通常是有意义的,比如在文档中对url自身进行定界,所以应该对其进行编码
0x00-0x1f,0x7f 受限,这些十六进制范围内的字符都在ascll字符集的不可打印区间内
>0x7f 受限,十六进制再次范围内的字符都不在ascll字符集的7位二进制范围内

2.4.4另外一点说明

你可能感到奇怪,为什么使用不安全的字符没有什么不好的事。对于某些传输协议来说,使用其中的一些字符不会出现问题,但对于程序开发人员来说,对非安全字符进行编码仍然是明智的。

应用程序要按照一定规范工作。客户端应用程序在其它应用程序发送任意url之前,最好把所有不安全的或受限字符进行转换。只要对所有不安全字符进行编码,这个url就是可以在各应用之间共享的规范形式;也就无需操心其它应用程序会被字符的任何特殊含义迷惑了

最合适判断是否需要对字符进行编码的程序就是从用户处获得url的源端应用程序。url的每个组件都会有自己的安全不安全字符,那些字符是安全的与方案有关,因此只有从用户那里接受url的应用程序才能够判断需要对那些字符进行编码。

另外,另一种极端的做法就是应用程序对所有字符都进行编码。尽管不建议这么做,但也没有强硬而严格的规则规定不能对安全字符进行编码;但在实际的应用程序中,有些应用程序可能会假定不对安全字符进行编码,这么做的话可能会产生一些奇怪的破坏行为。

有时,有些人会恶意的对额外的字符进行编码,以绕过那些对url进行模式匹配的应用程序,比如web过滤程序。

2.5方案的世界

方案 描述
http 超文本传输协议方案,除了没有用户名和密码之外,与通用的url格式相符。如果省略了端口,默认为80.基本格式:http://<host>:<port>/<path>?<query>#<frag>
https 方案https与http是一对,唯一的区别在于方案https使用了ssl加密。语法与http相同,默认端口443.
mailto mailto url指向的是E-mail地址由于mail的行为与其它方案都不同,所以mailto url的格式与标准url的格式也有所不同,因特网mail地址的语法记录在rfc833中。基本格式:mailto:<rfc-822-addr-spec>
ftp 文件传输协议url可以用来从服务器下载或上传文件,并获取ftp服务器上的目录结构内容列表。基本格式:ftp://<user>:<password>@<host>:<port>:<params>
rtsp,rtspu rtsp url 是可以通过实时流传输协议(real time streaming protocol)解析的音/视频媒体资源的标识符。rtspu中的u表示使用udp协议来获取资源的。基本格式:rspt(u)://<user>:<password>@<host>:<port>/<path>
file 表示指定一台主机上可直接的文件。各字段都采用通用格式。如果省略了主机名,就默认为正在使用url的本机地址。基本格式:file://<host>/<path>
news 用来访问一些特定的文章或新闻组。他有一个很独特的性质:news url自身包含的信息不足以对资源进行定位。新闻资源可以从多个服务器中获得,被称为位置无关的,因为他们的访问不依赖服务器。news url保留字符@区分指向新闻组的news url和指向特定文章的news url。基本格式:news:<newsgroup>,news:<news-article-id>
telnet 用于交互式访问业务。他表示的并不是对象自身,而是可以通过telnet访问的交互式程序。基本格式:telnet://<user>:<password>@<host>:<port>/

2.6未来展望

url是一种非常有用的工具,命名现有对象,而且很方便的包含了一些新格式。url提供了可以在各种因特网协议共享的统一命名的机制。

这种方案的缺点在于一旦自愿被移走了,url也就不在有效了。为了解决这个问题,因特网工程任务组(internet engineering task force ietf)已经对一种名为统一资源名(urn)进行了研究。

如果不是现在,那是什么时候

urn已经出现了一段时间,但到现在为止还没有投入使用。从url到urn的标准化的工作很缓慢。url仍然有很大的能量,所以还要等待时机。

推荐阅读更多精彩内容