URL
概述:就像这个世界上所有的东西都有一个标准化的名字,以帮助人们可以寻找各种资源一样,URL就是因特网中资源的标准化的名称。URL指向一条电子信息片段,告诉你它们位于何处,以及如何与之进行交互。
URL和URI
- URL是浏览器寻找信息时所需的资源位置。通过URL,人类和应用程序才能找到,使用并且共享因特网上大量的数据资源。
- URL是人们对HTTP和其他协议的常用访问点:一个人将浏览器指向一个URL,浏览器就会在幕后发送适当的协议报文来获取人们所期望的资源。
- URI是一类更通用的资源标识符,而URL是URI的一个子集。
- URI是一个通用的概念,由两个主要的子集URL和URN构成,URL是通过描述资源的位置来标识资源的,而URN则是通过名字来标识资源的,与资源所处的位置无关。
- HTTP规范将更通用的的概念URI作为其资源标识符,但是实际上,HTTP应用程序处理的只是URI的URL子集。
URL组成
http:://www.joes-hardware.com/seasonal/index.html
- 第一部分:(http)是URL方案(scheme):方案可以告知Web客户端怎么样访问资源,在这个例子中,URL说明要使用HTTP协议。
- URL可以通过HTTP之外的其他协议来访问资源。它们可以指向因特网上的任意资源或者是个人的E-mail账户:
mailto:president@whithouse.gov
或者通过其他协议(比如FTP协议)访问各种文件:
ftp://ftp.lots-o-books.com/pub/complete-price-list.xls
或者从流视频服务器上下载电影:
rtsp://www.joes-hardware.com:554/interview/cto_video
- URL可以通过HTTP之外的其他协议来访问资源。它们可以指向因特网上的任意资源或者是个人的E-mail账户:
- 第二部分:(www.joes-hardware.com)指向的是服务器的位置:这部分告知Web客户端位于何处。
- 第三部分:(/seasonal/index.html)资源路径:路径说明了请求的是服务器上哪个特定的本地资源。
- 第一部分:(http)是URL方案(scheme):方案可以告知Web客户端怎么样访问资源,在这个例子中,URL说明要使用HTTP协议。
URL的语法
URL提供了一种定位因特网上任意资源的手段,但是这些资源是可以通过各种不同的方案(比如HTTP、FTP、SMTP)来访问的,因此URL语法会随方案的不同而有所不同的。但是这并不意味着每种不同的URL方案都会有完全不同的语法,大部分URL都遵循通用的URL语法,而且不同的URL方案的风格和语法都有不少重叠。
- 通用格式(几乎没有哪个URL包含了所有这些组件)
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
最重要的三个部分就是方案(scheme)、主机(host)和路径(path)
- 通用格式(几乎没有哪个URL包含了所有这些组件)
组件 | 描述 | 默认值 |
---|---|---|
方案 | 访问服务器以获取资源时要使用哪种协议 | 无 |
用户 | 某些方案访问资源时需要用户名 | 匿名 |
密码 | 用户名后面可能要包含的密码,中间由冒号(:)分隔 | < E-mail地址 > |
主机 | 资源宿主服务器的主机名会点分IP地址 | 无 |
端口 | 资源宿主服务器正在监听的端口号。很多方案都有默认端口号 | 每个方案特有 |
路径 | 服务器上资源的本地名,由一个斜杠(/)将其与前面的URL组件分隔开。路径组件的语法是与服务器和方案有关的。 | |
参数 | 某些方案会用这个组件来指定输入的参数。参数为名/值对URL中可以包含多个参数字段,它们相互之间以及与路径的其余部分之间用分号(;)分隔 | |
查询 | 某些方案会使用这个组件传递 参数以激活应用程序(比如数据库、公告板、搜索引擎以及其他因特网网关)。查询组件的内容没有通用的格式。用字符“?”将其与URL其他组件分隔开。 | 无 |
片段 | 一小片或者一部分资源的名字。引用对象时,不会将frag字段传送给服务器;这个字段是在客户端内部使用的,通过字符“#”将其与URL的其他组件部分分隔开 | 无 |
用户名和密码组件:很多服务器都要求输入用户名和密码才会允许用户访问数据。FTP服务器就是这样一个常见的实例。例子:
ftp://ftp.prep.ai.mit.edu/pub/gnu
ftp://anonymous@ftp.perp.ai.mit.eud/pub/gnu
ftp://anonymous:my_password@ftp.perp.ai.mit.eud/pub/gnu
http://joe:joespasswd@www.joes-hardware.com/sales_info.txt第一个例子没有使用用户名和密码组件,只有标准的方案、主机和路径。如果某些应用程序使用的URL方案需要输入用户名和密码,比如FTP,但是用户没有提供,它通常会插入默认的用户名和密码。
比如,如果向浏览器输入一个FTP URL,但是没有指定用户名和密码,它就会插入anonymous(匿名用户)作为你的用户名,并且发送一个默认的密码。
第二个例子显示一个指定为anonymous的用户名。这个用户名与主机组件组合在一起,看起来就像E-mail地址一样。字符“@”将用户名和密码组件与URL其他部分分隔开来。
第三个例子中,指定了用户名和密码,两者之间由字符“:”分隔。
- 参数组件:对很多方案来说,只有简单的主机名和到达对象的路径是不够的。除了服务器正在监听的端口,以及是否能够通过用户名和密码访问的资源外,很多协议都还需要更多的信息才能工作。
- 负责解析URL的应用程序需要这些协议的参数来访问资源。否则请求的服务器可嫩不会提供服务或者是提供错误的服务。比如像FTP协议,有两种传输的模式,二进制和文本形式。用户肯定不希望以文本形式来传送二进制图片。
ftp://prep.ai.mit.edu/pub/gnu;type=d
这个例子中有一个参数type,值为d
- 查询组件
http://www.joes-hardware.com/inventory-check.cgi?item=12731
- 问号右边的内容就是查询(query)组件。URL的查询组件和标识网关资源的URL路径组件一起被发送给网关资源。基本上可以将网关当作访问其他应用程序的访问点。
- 除了对有些不合规则的字符需要特别处理之外,对查询组件的格式没什么要求。按照常规,很多网关都希望查询字符串以一系列”名/值”对的形式出现,名值对之间用字符“分隔”。
- 片段:有些资源类型,除了资源级之外,还可以做进一步的划分。比如,对一个带有章节的大型文本文档来说,资源的URL会只想整个文档,但是理想的情况是,能够指定资源中的某些章节。
http://www.joes-hardware.com/tools.html#drills
- HTTP服务器通常只处理整个对象,而不是对象的片段,客户端不能将片段传送给服务器。浏览器从服务器获得了整个资源之后,会根据片段来显示你感兴趣的那部分的资源。
URL快捷方式:Web客户端可以理解并使用几种URL快捷方式。
- 相对URL:URL有两种方式:绝对的和相对的。相对URL是不完整的。要从相对的URL中获取访问资源所需的全部信息,就必须相对于另一个,被称为其基础的URL进行解析。
- 带有相对URL的HTML代码片段(例1)
<HTML>
<HEAD><TITLE>Joes's Tools</TITLE></HEAD>
<BODY>
<H1>Tools Page</H1>
<H2> Hammers <H2>
<P> Joe's Hardware Online has the largest selection of <A HREF="./hammers.html">hammers
</A> on earth.
</BODY>
</HTML>
在这个HTML文档中有一个包含了URL ./hammers.html的超链接。
使用缩略形式的相对URL语法,HTML的编写者就可以省略URL中的方案、主机和其他一些组件。这些组件可以从它们所属资源的基础URL中推导出来。 - 基础URL:相对URL只是URL的片段或者一小部分。处理URL的应用程序(比如浏览器)要能够在相对和绝对URL之间进行转换。转换处理的第一步就是找到基础的URL
- 在资源中显示提供基础URL
- 有些资源会显示地指定基础URL。比如,HTML文档中可能会包含一个定义了基础URL的HTML标记 < BASE >,通过它来转换那个HTML文档中的所有相对URL。
- 封装资源的基础URL
- 如果在一个没有显示指定基础URL的资源中发现了一个相对URL,如例2-1所示,可以将它所属资源的URL作为基础
- 没有基础的URL
- 在某些情况下没有基础的URL,这通常意味着你有一个相对URL;但是有时可能 知识一个不完整的或者损坏了的URL。
- 在资源中显示提供基础URL
- 相对URL转换成绝对URL:将相对URL和基础URL划分成组件段,是在分解URL,只要将基础和相对URL划分成了组件,就可以应用以下算法来完成转换:
这个算法将一个相对URL转换成其绝对模式,之后就可以用它来应用资源了。
可以对例1中的./hammers.html实例使用上述算法:
(1)路径为./hammers.html,基础URL为http://www.joes-hardware.com/tools.html。
(2)方案为空,沿着图标的左半边向下处理,继承基础URL方案(HTTP)。
(3)至少一个组件非空,一直处理到底端,继承主机和端口组件。
(4)将来自相对URL(路径:./hammers.html)的组件与我们继承来的组件(方案:http,主机:www.joes-hardware.com,端口:80)合并起来,得到新的绝对URL:http://www.joes-hardware.com/hammers.html.
自动扩展URL
有些浏览器会在用户提交URL之后,或者在用户输入的时候尝试着自动扩展URL,这就为用户提供了一条捷径:用户不需要输入完整的URL,浏览器会自动帮你进行扩展。
“自动扩展”特性有两种方式:
- 主机名扩展
在主机名扩展中,只要有些小提示,浏览器通常就可以在没有帮助的情况下,将你输入的主机名扩展为完整的主机名。
比如,如果在地址栏中输入yahoo,浏览器就会自动在主机名中插入www.和.com,构建出www.yahoo.com。如果找不到与yahoo匹配的站点,有些浏览器会放弃之前尝试几种扩展形式。浏览器通过这些简单的技巧来节省你的时间,减少找不到的可能。
但是这些主机名扩展技巧可能会成为其他一些HTTP应用程序带来问题,比如代理。(以后解释)
- 历史扩展
浏览器用来节省用户输入URL的时间的另一种技巧是,将以前用户访问过的URL历史存储起来。当你输入URL时,它们就可以将你输入的URL与历史记录中的URL的前缀进行匹配,并且提供一些完整的选项供你选择。因此,如果你输入了一个以前访问过的URL的开始部分,比如http://www.joes-,浏览器就可能会建议使用http://www.joes-hardware.com。然后你就可以选择这个地址,不用输入完整的URL
需要注意的是,与代理共同使用时,URL自动扩展的行为可能会有所不同。
URL字符集
- URL是可以移植的(portable)。它要统一地命名因特网上的所有资源,这也意味着要通过各种不同的协议来传送这些资源。这些协议在传输数据时都会使用不同的机制,所以设计URL使其可以通过任意因特网协议安全地传输是很重要的。
- 安全传输意味着URL的传输不能丢失信息。有些协议,比如传输电子邮件的简单邮件传输协议(SMTP),所使用的传输方法就会剥去一些特定的字符,为了避免这些问题,URL只能使用一些相对较小的、通用的安全字母表中的字符。
- 除了希望URL可以被所有的因特网协议进行传输之外,设计者们还希望URL是可读的。因此,即使不可见、不可打印的字符能够穿过邮件程序,从而成为可抑移植的,也不能在URL中使用。
- URL还得是完整的,这就使问题变得更加复杂了。URL的设计者们认识到有时人们可能会希望URL中包含除通用的安全字母表之外的二进制数据或者字符。因此需要一些转义机制,能够将不安全的字符编码为安全字符,再进行传输。
URL字符集
URL字符集如何实现了可移植性和完整性?
1.默认的计算机系统字符集通常都倾向于以英文为中心。从历史上来看,很多计算机应用程序使用的都是US-ASCII字符集。US-ASCII使用7位二进制码来表示英文打字机提供的大多数按键和少数用于文本格式和硬件通知的不可打印控制字符。
2.由于US-ASCII的历史悠久,所以其可移植性很好。但是它却不能支持使用其他语言中的很常见的变体字符。
3.而且有些URL中还会包含任意的二进制数据。认识到对完整性的需求之后,URL的设计者就将转义序列集成了进去。通过转义序列,就可以用US-ASCII字符集的有限子集对任意字符值或数据进行编码了,这样就实现了可移植性和完整性。编码机制
为了避免安全字符集表示法带来的限制,设计了一种编码机制,用来在URL中表示各种不安全的字符。这种编码机制就是通过一种”转义”表示法来表示不安全的字符的,这种转义表示法包含一个百分号(%),后面跟着两个表示字符ASCII码的十六进制数。
表 一些编码字符示例
字符 | ASCII码 | 实例URL |
---|---|---|
~ | 126(0x7E) | http://www.joes-hardware.com/%7Ejoe |
空格 | 32(0x20) | http://www.joes-hardware.com/more%20tools.html |
% | 37(0x25) | http://www.joes-hardware.com/100%25satisfaction.html |
- 字符限制
在URL中,几个字符被保留起来,有着特殊的含义。有些字符不在定义的US-ASCII字符集中,还有些字符会与某些因特网网关和协议产生混淆,因此不赞成使用。
字符 | 保留/受限 |
---|---|
% | 保留作为编码字符的转义标志 |
/ | 保留作为路径组件中分隔路径段的定界符 |
. | 保留在路径组件中使用 |
.. | 保留在路径组件中使用 |
# | 保留作为分段定界符使用 |
? | 保留作为查询字符串定界符使用 |
; | 保留作为参数定界符使用 |
: | 保留作为方案、用户/口令,以及主机/端口组件的定界符使用 |
$,+ | 保留 |
@ & = | 在某些方案的上下文中有特殊的含义,保留 |
{ } | \ ^ ~ [ ] ‘ | 由于各种传输Agent代理,比如各种网关的不安全代理,使用受限 |
< > “ | 不安全;这些字符在URL范围之外通常是由意义的,比如在文档中对URL自身进行定界,所以应该对其进行编码 |
0x00-0x1F,0x7F | 受限,这些十六进制范围内的字符通常都在US-ASCII字符集是不可打印区间 |
>0x7F | 受限,十六进制在此范围内的字符都不在US-ASCII字符集的7位二进制范围内 |
另外一点说明
1.读者可能会感到奇怪,为什么使用一些不安全字符的时候并没有发生不好的事情。比如,你可以访问http://www.joes-hardware.com/~joe而不用对“~”字符进行编码。对某些传输协议来说,这并不是问题,但是对于应用程序开发人员来说,对非安全字符进行编码仍然是明智的选择。2.应用程序要按照一定规范工作,客户端应用程序在向其他应用程序发送任意URL之前,最好把不安全的或者是受限字符都进行转换(指客户端应用程序),只有对所有的不安全字符都进行编码,这个URL就是可在各应用程序之间共享的规范形式;也就无需操心其他应用程序会被字符的任何特殊含义所迷惑了。
3.最适合判断是否需要对字符进行编码的程序就是从用户处获取URL的源端应用程序。URL的每个组件都会有自己的安全/不安全字符,哪些字符是安全/不安全的与方案无关,因此只有从用户那里接受URL的应用程序才能够判断需要对哪些字符进行编码。
4.当然另一种极端的做法就是应用程序对所有的字符都进行编码。尽管并不建议这么做,但也没有什么强硬且严格的规则规定不能对那些安全字符进行编码;但在实际应用中,有些应用程序可能会假定不对安全字符进行编码,这么做的话可能会产生一些奇怪的破坏性行为。
5.有时候,有些人会恶意的对额外的字符进行编码,以绕过那些对URL进行匹配的应用程序—–比如,Web过滤程序。对安全的URL组件进行编码会使模式匹配程序无法识别出它们索要搜寻的模式。
总之,解释URL的应用程序必须在处理URL之前对其进行解码。
方案的世界
常见的方案格式
方案 | 描述 |
---|---|
http | 超文本传输协议方案,除了没有用户名和密码之外,与通用的URL格式相符。如果省略了端口,就默认为80。基本格式:http://<host>:<port>/<path>?<query>#<frag> |
https | 方案https和方案http是一对。唯一的区别在于方案https使用了网景的SSL,SSL为http提供了端到端的加密机制。其语法与http的语法相同,默认端口为443。基本格式:https"//<host>:<port>/<path>?<query>#<frag> |
mailto | Mailto URL 指向的是E-mail地址。由于E-mail的行为与其他方案有所不同(它并不指向任何可以直接访问的对象),所以mailto URL的格式与标准URL的格式有所不同。基本格式:mailto:<RFC-822-addr-spec> 实例:mailto:joe@joes-hardware.com |
ftp | 文件传输协议URL可以用来从FTP服务器上下载或向其上载文件,并获取FTP服务器上的目录结构内容的列表。在Web和URL出现之前FTP就已经存在了。Web应用程序将FTP作为一种数据访问方案使用。URL语法遵循通用格式。 |
rtsp,rtspu | RTSP URL是可以通过实时流传输协议(Real Time Streaming Protocol)解析的音/视频媒体资源的标识符。方案rtspu中的u表示它是使用UDP协议来获取资源的。基本格式:{rtsp/rtspu}://<user>:<password>@<host>:<port>/<path> |
file | 方案file表示一台指定主机(通过本地磁盘,网络文件系统或者其他一些文件共享系统)上可直接访问的文件。各自段都遵循通用格式。如果省略了主机号,就默认为正在使用的URL的本地主机 |
telne | 方案Telnet用于访问交互式业务。它表示的并不是对象自身,而是可通过telnet协议访问的交互式应用程序(资源)。基本格式:telnet://<user>:<password>@<host>:<port>/ |