URL与资源

URL 与资源

浏览因特网资源

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

  URI 是一类更通用的资源标识符,URL 实际上是它的一个子集。URI 是一个通用的概念,由两个主要的子集 URL 和 URN 构成。

  http 规范将更通用的概念 URL 作为其资源标识符,但实际上,http 应用程序处理的只是 URI 的 URL 子集。再次强调,我将不加区分的使用 URI 和 URL,但你我们讲的基本上都是 URL。

  以http://buaihechengzizhi.com/img/logo2.jpg 为例,如上次所说,URL 的第一部分是方案,在本例中是 http,第二部分是服务器的位置,第三部分是资源路径。

黑暗岁月

  在 web 和 url 出现之前,人们要靠分类杂乱的应用程序来访问分布在网络中的数据,大多数人都不会幸运地拥有所有合适的应用程序,或者不能够理解,也没有足够的耐心来使用这些程序。

URL 的语法

  URL 提供了一种定位因特网上任意资源的手段,但这些资源是可以通过各种不同的方案(HTTP,FTP,SMTP)访问的,因此 URL 语法会随方案的不同而有所不同。

  这意味着每种不同的 URL 方案都会有完全不同的语法吗?很幸运,不是。大多数 URL 都遵循通用的 URL 语法,而且不同 URL 方案的风格和语法都有相当的重叠。

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

  < 方案 >://< 用户 >:< 密码 >@< 主机 >:< 端口 >/< 路径 >;< 参数 >?< 查询 >#< 片段 >

没有一个 URL 是包含上述全部组件的,最重要的三部分无非就是 方案 (scheme),主机(host) 和路径 (path) 而已。

组件 描述 默认值
方案 访问服务器以获取资源时要使用的协议
用户 某些方案访问资源时需要的用户名 匿名
密码 可能的密码,和用户名之间用冒号分隔 E-mail 地址
主机 资源宿主服务器的主机名或点分 IP 地址
端口 资源宿主服务器正在监听的端口号 每个方案特有
路径 服务器上资源的本地名,由一个斜杠与前面的 URL 组件分隔
参数 某些方案会用这个组件指定输入参数,为键值对,多个之间用分号分隔
查询 某些方案会用这个组件去激活应用程序,如数据库等,用字符?与其他组件分隔
片段 一小片或一部分资源的名字,是客户端内部使用的,用 #与其他组件分隔

方案

  这个组件规定了 使用什么协议 ,即如何访问指定资源。方案组件必须以一个字母符号开始,由第一个“:”符号将其与 URL 其余部分分隔开来。方案名是 大小写无关 的。

主机与端口

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

  主机组件标识了因特网上能够访问的宿主机器,可以用 www.buaihechengzizhi.com 这种域名来表示,也可用 47.104.14.19 来表示。端口组件标识了服务器正在监听的端口,对下层使用了 TCP 协议的 http 来说,默认端口号为 80。

用户名和密码

  很多服务器都要求输入用户名和密码才会允许用户访问数据,最常见的便是 FTP 服务器。

路径

  URL 的路径组件说明了资源位于服务器的什么地方,通常很像一个分级的 文件系统路径 。用字符“/”将 http URL 的路径组件划分成一些路径段, 每个路径段都有自己的参数组件

参数

  对很多方案来说,只有简单的主机名和到达对象的路径是不够的。除了服务器正在监听的端口,以及是否能够通过用户名和密码访问资源外, 很多协议还需要更多的信息才能工作。

  负责解析 URL 的应用程序需要这些协议参数来访问资源。否则,另一端的服务器可能就不会为请求提供服务,或者更糟糕的是,提供错误的服务(例如以文本形式传输二进制图片)

  为了向应用程序提供它们所需的输入参数,以便正确地与服务器进行交互,URL 中有一个参数组件,是一个 名值对列表 ,由字符“;”将其与 URL 中的其余部分以及各名值对分隔开,比如:ftp://prep.ai.mit.edu/pub/gnu;type=d

查询字符串

  很多资源,比如数据库服务,都是可以通过提问题或进行查询来缩小所请求资源类型范围的。例如http://www.joes-hardware.com/inventory-cheek.cgi?item=111

  这个 URL 的大部分都与我们见过的类似,唯独?后面的是新出现的,这部分便是查询(query)组件。URL 的查询组件和标识网关资源的 URL 路径组件一起被发送给网关资源。基本上可以将网关当作访问其他应用程序的访问点(在以后会详细讨论)

  除了有些不合规则的字符需要特别处理之外,对查询组件的格式没有什么要求。按照常规,很多网关都希望查询字符串以一些列“名 / 值”对的形式出现,名值对之间用字符“&”分隔

片段

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

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

  片段挂在 URL 的右手边,最前面有一个字符“#”。

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

URL 快捷方式

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

相对 URL

  URL 有两种方式:绝对 相对 。到目前为止,我们说过的都是绝对 URL,它包含访问资源所需要的全部信息。

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

  相对 URL 是 URL 的一种便捷缩略记法,如:

<a href="./test.html">TEST</a>

  这个./test.html 看起来不完整,但实际上是个合法的相对 URL,可以 相对于它所在文档的 URL 进行解释 ,即当前路径下的 test.html。

  使用缩略形式的相对 URL 语法,HTML 的编写者就可以省略 URL 中的方案,主机和其他一些组件了,这些组件可以从它们所属资源的基础 URL 中推导出来,其他资源的 URL 也可以用这种缩略形式表示。

  相对 URL 只是 URL 的片段或一小部分,浏览器要能够在相对和绝对 URL 之间进行转换。需要注意的是,相对 URL 为保持一组资源的便携性提供了一种便捷方式,在搬移一组文档时,仍然能够保持连接的有效性,因为相对 URL 都是相对于新基础进行解释的。

基础 URL

转换处理的第一步就是找到基础 URL,可以来自几个不同的地方:

  • 在资源中显式提供

HTML 文档中可能包含了一个标记 <BASE>,通过它来转换文档中所有相对 URL

  • 封装资源的基础 URL

如果没有显式指定,就把它所属的 URL 作为基础

  • 没有基础 URL

你只有一个相对 URL,可能只是一个不完整或损坏了的 URL

解析相对引用

要将相对 URL 转换为一个绝对 URL,下一步要做的就是将相对 URL 和基础 URL 划分成组件段。实际上,这样只是在解析 URL,但这种做法会将其划分成一个个组件,因此被称作分解(decomposing)URL。只要将基础和相对 URL 划分成了组件,就可以用下图的算法来完成转换了:

1.png

这个算法最初是在 RFC 1808 种制定,后来被合并到了 RFC 2396 中。

自动扩展 URL

有些浏览器会在用户提交 URL 之后,或者在用户输入的时候尝试着自动扩展:用户不需要输入完整的 URL。

  • 主机名扩展

在主机名扩展中,只要有些小提示,浏览器通常就可以在没有帮助的情况下,将你输入的主机名扩展为完整的主机名,比如输入 baidu,就可以自动插入 www 和.com,组成 www.baidu.com。

  • 历史扩展

将以前用户访问过的 URL 历史储存起来。

奇怪的字符

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

   安全 传输意味着 URL 的传输不能丢失信息,为了避开这个问题,URL 只能使用一些相对较小的,通用的安全字母表中的字符。

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

  URL 还得是 完整的 ,这就使问题复杂化了,既要马跑得快又不想给马吃草,因此,需要有一种转义机制,能够将不安全的字符编码转换为安全字符,再进行传输

URL 字符集

  默认的计算机系统字符集通常都倾向于以英语为中心,所以其可移植性很好,但虽然美国用户使用起来很便捷,它却不支持在各种欧洲语言或全世界数十亿人使用的数百种非罗马语言中很常见的变体字符。而且有些 URL 中还包含任意的二进制数据。

  认识到完整性的需求之后,URL 的设计者就将转义序列集成了进去,通过转义序列,就可以用 US-ASCII 的字符集的有限子集对任意字符值或数据进行编码了。这样就实现了可移植性和完整性。

编码机制

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

字符限制

  在 URL 中,有几个字符被保留了起来,有着特殊的含义。如 % / . .. # ? ; : $ + @ & = {} | ^ ~ [] '< >" 0x00-0x1F0x7F,>0x7F

常见的方案格式:

方案 描述
http 超文本传输协议方案,默认端口号 80
https与 http 是一对,区别在于使用了 SSL,为 http 连接提供了端对端的加密,默认端口 443
mailtoMailto URL 指向的是 E -mail 地址
ftp 文件传输协议 URL 可以用来从 FTP 服务器上下载或上传文件,默认端口 21
rtsp,rtspu是可以通过实时流传输协议解析的音 / 视频媒体资源的标识符,默认端口 554
file表示一台主机指定主机上可直接访问的文件,如果没有主机名,就是本机
news 访问一些特定的文章或新闻组,它所包含的信息不足以对资源进行定位
telnet 用于交互式业务,表示可通过 telnet 协议访问的交互式应用程序

URL 是完美的吗

  不是,URL 表示的是实际的地址,而不是准确的名字,这意味着 URL 会告诉你资源此时处于什么位置,但如果资源被移走了,URL 就不再有效了。如果有了对象的准确名称,则不论其处于何处都能找到这个对象就很完美了,因此,URN 出现了。

  永久统一资源定位符(PURL)是用 URL 来实现 URN 功能的一个例子,其基本思想是搜索资源的过程中引入另一个中间层,通过一个中间资源定位符服务器对资源的实际 URL 进行登记和跟踪。

什么时候可以实现

  URN 的思想已经推出一段时间了,你可能会问,为什么它到现在还没有被投入使用。实际上,从 URL 转换成 URN 是一个巨大的过程,标准化工作的进程很缓慢,而且通常都有很充分的理由。支持 URN 需要进行很多改动——标准主体的一致性,对各种 http 应用程序的修改等。做这种改动需要进行大量的工作,而且 URL 仍然还有很大的能量,还要等待合适的时机才能进行转换。

  在 web 爆炸性增长的过程中,因特网用户——包括从计算机科学家到普通因特网用户的每一个人——都已经学会使用了 URL。在备受困扰的同时,人们已经学会了如何使用 URL,以及如何对付它们的一些缺陷,URL 有一些限制,但这并不是 web 开发社区所面临的最紧迫的问题。

  在可预见的未来,因特网资源仍然会以 URL 来命名,它们无处不在。