HTTP(二)HTTP 资源
目录
¶概述
❓什么是资源?
最简单的 Web 资源就是 Web 服务器文件系统中的静态文件,这些文件可以是任意格式,如:文本文件(TXT)、HTML 文件、微软的 Word 文件、Adobe 的 Acrobat 文件、 JPEG 图片文件、AVI 电影文件等等。
🎶需要注意的是,资源不一定非得是静态文件,资源还可以是根据需要生成内容的软件程序(动态文件)
¶资源类型
❓HTTP 对每种要通过 Web 传输的对象都打上了名为 MIME 类型的数据格式标签,为什么要设计MIME
类型?
¶定位资源
每个 Web 服务器资源都有一个名字,这样客户端就可以说明它们感兴趣的资源是什么了。服务器资源名被称为统一资源标识符(Uniform Resource Identifier, URI)。URI 就像因特网上的邮政地址一样,用于在计算机的世界内唯一标识并定位信息资源
¶URI
URI 是一类通用的资源标识符,由两个主要的子集 URL
和 URN
构成。URL 是通过描述资源的位置来标识资源的,而 URN 则是通过名字来识别资源的,与资源当前所处位置无关
¶URL
URL 是浏览器寻找信息时所需的资源位置。URL 描述了一台特定服务器上某资源的特定位置,通过 URL 可以明确说明如何从一个精确、固定的位置获取资源。常见的 URL 实例如下:
URL | 描述 |
---|---|
http://www.oreilly.com/index.html | O’Reilly & Associates 公司的主 URL |
https://pineapple-man.github.io/assets/images/logo.jpg | 我博客 logo 的 URL |
ftp://joe:tools4u@ftp.joes-hardware.com/locking-pliers.gif | 用 FTP 作为访问协议的 locking-pliers.gif 图片文件的 URL |
大部分 URL 都遵循如下这样一种标准格式,这种格式包含三个部分
1 | scheme://PATH/TO/HOST/:PORT/PATH/TO/RESOURCE |
部分 | 含义 |
---|---|
scheme:// | URL 的第一部分被称为方案(scheme),说明了访问资源所使用的协议类型。这部分通常是 HTTP 协议(http://)以告知 Web 客户端怎样访问资源 |
PATH/TO/HOST/:PORT | 第二部分给出了服务器的因特网地址(比如,www.joes-hardware.com)告知 Web 客户端资源位于何处 |
/PATH/TO/RESOURCE | 指定了 Web 服务器上的某个资源路径(比如,/specials/saw-blade.gif)路径说明了请求的是服务器上哪个路径下的本地资源 |
URL 可以通过 HTTP 之外的其他协议来访问资源。它们可以指向因特网上的任意资源,或者个人的 E-mail 账户,比如mailto:president@whitehouse.gov
,或者通过其他协议(比如 FTP 协议)访问的各种文件:ftp://ftp.lots-o-books.com/pub/complete-price-list.xls
URL 提供了一种统一的资源命名方式,大多数 URL 都有同样的:scheme://PATH/TO/HOST/:PORT/PATH/TO/RESOURCE
结构。因此,对网络上的每个资源来说,命名资源的方法只有一种,这样不管是谁都可以用名字来找到这个资源
¶URN
URI 的第二种形式就是统一资源名(URN),URN 是作为特定内容的唯一名称使用的,与资源所在地无关。使用这些与位置无关的 URN,就可以将资源四处搬移,通过 URN 可以用同一个名字通过多种网络访问协议来访问资源
¶URL 的语法
URL 提供了一种定位因特网上任意资源的手段,但这些资源是可以通过各种不同的方案(比如 HTTP、FTP、SMTP)来访问的,因此 URL 语法随方案的不同而有所不同
🤔这是不是意味着每种不同的 URL 方案都会有完全不同的语法呢?
1 | <scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag> |
几乎没有哪个 URL 中包含了所有这些组件,URL 最重要的三个部分是方案(Scheme)、主机(host)和路径(path)
组件 | 描述 | 默认值 |
---|---|---|
方案 | 访问服务器以获取资源时要使用哪种协议 | 无 |
用户 | 某些方案访问资源时需要的用户名 | 匿名 |
密码 | 用户名后面可能要包含的密码,中间由冒号(:)分隔 | <E-mail 地址 > |
主机 | 资源宿主服务器的主机名或点分 IP 地址 | 无 |
端口 | 资源宿主服务器正在监听的端口号。很多方案都有默认端 口号(HTTP 的默认端口号为 80) | 每个方案特有 |
路径 | 服务器上资源的本地名,由一个斜杠(/)将其与前面的 URL 组件分隔开来。路径组件的语法是与服务器和方案有关的(本章稍后会讲到 URL 路径可以分为若干个段,每段都可以有其特有的组件。 | 无 |
参数 | 某些方案会用这个组件来指定输入参数。参数为名 / 值对。 URL 中可以包含多个参数字段,它们相互之间以及与路径 的其余部分之间用分号(;)分隔 | 无 |
查询 | 某些方案会用这个组件传递参数以激活应用程序(比如数 据库、公告板、搜索引擎以及其他因特网网关)。查询组件的内容没有通用格式。用字符? 将其与 URL 的其余 部分分隔开来 | 无 |
片段 | 一小片或一部分资源的名字。引用对象时,不会将 frag 字 段传送给服务器;这个字段是在客户端内部使用的。通过 字符“#”将其与 URL 的其余部分分隔开来 | 无 |
¶方案
¶主机与端口号
¶用户名和密码
很多服务器都要求输入用户名和密码才会允许用户访问数据(如今使用的不多,大部分会在前后端程序中进行认证操作,不在 URL 上限制用于)。FTP 服务器就是这样一个常见的实例,这里有几个例子:
第一个例子没有用户或密码组件,只有标准的方案、主机和路径。如果某应用程序使用的 URL 方案要求输入用户名和密码,但用户没有提供,它通常会插入一个默认的用户名和密码
如果向浏览器提供一个 FTP URL,但没有指定用户名和密码,它就会插入 anonymous(匿名用户)作为你的用户名,并发 送一个默认的密码(Internet Explorer 会发送 IEUser,Netscape Navigator 则会发送 mozilla)
¶路径
¶参数
负责解析 URL 的应用程序需要这些协议参数来访问资源,如果缺少相关的协议参数可能访问不到请求的服务。为了向应用程序提供它们所需的输入参数,以便正确地与服务器进行交互,URL 中有一个参数组件。这个组件就是 URL 中的键值对列表,由字符 ;
将各种参数分隔开来,丰富了应用程序提供访问资源的方式
比如:
¶查询字符串
这个 URL 的大部分都与我们见过的其他 URL 类似。只有问号(?)右边的内容是新出现的。这部分被称为查询(query)组件。URL 的查询组件和标识网关资源的 URL 路径组件一起被发送给网关资源。基本上可以将网关当作访问其他应用程序的访问点
除了有些不合规则的字符需要特别处理之外,对查询组件的格式没什么要求。按照常规,很多网关都希望查询字符串以一系列 key=value
的形式出现,键值对之间用字符 &
分隔:
1 | http://www.joes-hardware.com/inventory-check.cgi?item=12731&color=blue |
¶片段
为了引用部分资源或资源的一个片段,URL 支持使用片段(frag)组件来表示一个资源内部的片段。比如,URL 可以指向 HTML 文档中一个特定的图片或小节片段挂在 URL 的右手边,最前面有一个字符 #
¶URL 快捷方式
Web 客户端可以理解并使用几种 URL 快捷方式。相对 URL 是在某资源内部指定一个资源的便捷缩略方式。很多浏览器还支持 URL 的自动扩展,也就是用户输入 URL 的一个关键(可记忆的)部分,然后由浏览器将其余部分填充起来
¶相对 URL
相对 URL 是 URL 的一种便捷缩略记法。如果你手工写过 HTML 的话,就会发现相对 URL 是多么便捷了。下面是一个嵌入了相对 URL 的 HTML 文档实例
¶基础 URL(Base URL)
转换处理的第一步就是找到 Base URL,Base URL 是作为相对 URL 的参考点使用的,可以来自以下几个不同的地方:
¶解析相对引用
要将相对 URL 转换为一个绝对 URL,下一步要做的就是将相对 URL 和基础 URL 划分成组件段,实际上,这样只是在解析 URL,但这种做法会将其划分成一个个组件,因此通常会称作分解(decomposing)URL。只要将基础和相对 URL 划分成了组件,就可以使用相关的算法将一个相对 URL 抓换成其绝对模式,之后就可以用它来引用资源了
¶自动扩展 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 的传输不能丢失信息。有些协议,比如传输电子邮件的简单邮件传输协议(Simple Mail Transfer Protocol,SMTP),所使用的传输方法就会剥去一些特定的字符。为了避开这些问题,URL 只能使用一些相对较小的、通用的安全字母表中的字符。
除了希望 URL 可以被所有因特网协议进行传送之外,设计者们还希望 URL 也可供人类阅读。因此,即使不可见、不可打印的字符能够穿过邮件程序,从而成为可移植的,也不能在 URL 中使用(其中最重要的一个字符就是空格)
URL 还得是完整的,这就使问题变得更加复杂了。URL 的设计者们认识到有时人们可能会希望 URL 中包含除通用的安全字母表之外的二进制数据或字符。因此,需要有一种转义机制,能够将不安全的字符编码为安全字符,再进行传输
¶URL 字符集
¶编码机制
为了避开安全字符集表示法带来的限制,人们设计了一种编码机制,用来在 URL 中表示各种不安全的字符。这种编码机制就是通过一种转义表示法表示不安全字符的,这种转义表示法包含一个百分号(%
),后面跟着两个表示字符 ASCII 码的 十六进制数
字符 | ASCII 码 | 示例 |
---|---|---|
~ | 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 自身 进行定界(比如 http://www.joes-hardware.com),所以应该对其进行编码 |
0x00-0x1F,0x7F | 受限,这些十六进制范围内的字符都在 US-ASCII 字符集的不可打印区间内 |
>0x7F | 受限,十六进制值在此范围内的字符都不在 US-ASCII 字符集的 7 比特范围内 |
¶其他
📓总之,解释 URL 的应用程序必须在处理 URL 之前对其进行解码
¶总结
在可预见的未来,因特网资源仍然会以 URL 来命名。它们是 Web 能够成功非常重要的部分。其他命名方案想要取代 URL 还要一段时间。但是,URL 由于有其局限型,可能会出现新的标准(可能是 URN),对这种标准进行部署会解决其中的某些问题