一:HTTP概述:
本节内容主要是对http的简要介绍,通过本节的学习,我们可以知道http是如何工作的。http客户端和http服务器共同构成了万维网的基本组件,最常见的http客户端就是web浏览器。因特网上每天都会传送大量的图片,HTML页面,视频,音频等资源。这些资源都是存放在各个服务器上的,我们通过浏览器对服务器发起请求就可以获取相应的资源。这个请求的发起和获取服务器的响应少不了http的支持,而且http能够保证我们请求的资源是完整的,这主要是因为http使用了一种可靠的数据传输协议TCP/IP,即使数据来自地球的另一端,它也能够保证数据在传输的过程中不会被破坏或产生混乱。
事务:一个http事务由一条请求命令和一个响应结果组成,请求命令指的是从客户端发往服务器,响应结果指的是从服务器发往客户端。这种通信是通过名为http报文的格式化数据块进行的。
方法:http支持几种不同的请求命令,这些命令又被称为方法,在每条请求报文中都会包含一个命令。GET, PUT, DELETE, POST, HEAD。
状态码: 每条http响应报文都会携带一个三位数字的状态码已告知客户端请求是否成功或者是否需要采取其他动作。伴随着数字状态码还会有一条解释性的原因短语。
报文: http报文是由一行一行的简单字符串组成的,都是纯文本(主体除外,主体也可以包含二进制数据),不是二进制代码。包含起始行,首部字段,主体三部分。
http的历史版本:
HTTP/0.9:HTTP的1991原型版本称为HTTP/0.9,这个协议有很多严重的设计缺陷,只应该用于和老客户端的交互,它支持GET方法,不支持多媒体内容的MIME类型,各种HTTP首部或者版本号。定义它的初衷是 为了获取简单的HTML对象。
HTTP/1.0:1.0是第一个得到广泛应用的HTTP版本,它添加了版本号,各种HTTP首部,一些额外的方法,以及对多媒体对象的处理,这使得网页包含生动地图片成为可能。
HTTP/1.0+: 在20世纪90年代中叶,很多流行的web客户端和服务器都在飞快的向http中添加各种特性,以满足快速扩张且在商业上十分成功的万维网的需要。其中包含持久的keep-alive连接,虚拟主机支持和代理,这些成为了非官方的事实标准,通常这个非正式的HTTP扩展版本被称为HTTP/1.0+。
HTTP/1.1: 重点关注的是校正HTTP设计中的结构性缺陷,明确语义,引入重要的性能优化措施,删除一些不好的特性。还对20世纪90年代末正在发展中的更复杂的web应用程序和部署方式进行了支持。它是当前使用的HTTP版本。
HTTP-NG: 是1.1后继结构的原型建议,它重点关注的是性能的大幅优化,以及更加强大的服务逻辑远程执行框架。
web的其他结构组件:
代理:位于客户端和服务器之间的HTTP中间实体。接受所有客户端的http请求,并将这些请求转发给服务器(可能会对请求进行修改)。可以对请求和响应进行过滤。
缓存:HTTP 的仓库,使常用页面的副本可以保存在离客户端更近的地方。它是一种特殊的HTTP代理服务器。
网关:是一种特殊的服务器,通常用于将HTTP流量转化成其他的协议。它接受请求的时候就好像自己是资源的源端服务器一样,客户端可能并不知道自己在与一个网关通信。例如一个HTTP/FTP网关会通过HTTP请求接收对FTP URI的请求,但通过FTP协议来获取文档,得到的文档会被封装成一条HTTP 报文,发送给客户端。
隧道:它建立之后,就会在两条连接之间对原始数据进行盲转发的HTTP应用程序,常用来在一条或多条HTTP连接上转发非HTTP 数据,转发时不会窥探数据。
Agent代理: 可以发起自动HTTP请求的半智能的web客户端程序。有用户Agent代理(web机器人,网络蜘蛛)和HTTP Agent代理(web浏览器)。
URL与资源
url 是浏览器寻找信息时所需的资源位置,通过URL,应用程序才能找到使用并共享因特网上大量的资源。在浏览器里输入一个URL,浏览器就会在幕后发送适当的协议报文来获取资源。URI是统一资源标识符,url是他的一个子集,uri还包括urn,urn通过名字来识别资源,跟位置无关,但是现在还未使用。现在,一般的应用程序处理的都是uri的子集url。
url不仅可以支持http协议访问,也支持其他的网络协议,如ftp,url是一种统一的资源命名方式,对网络中的每个资源以及获取这些资源的每种方式来说,命名资源的方法只有一种,这样不管是谁都可以用名字来找到这个资源了。
URL的语法:URL提供了一种定位因特网上任意资源的手段,但这些资源是可以通过各种不同的方案来访问的,因此,URL语法会随着方案的不同而不同。大多数的URL都建立在下面这个由9部分构成的通用格式上,
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
几乎没有哪个URL中包含了所有这些组件,最重要的三个部分是方案scheme,主机host和路径path。
方案实际上是规定如何访问资源的主要的标识符,它告诉负责解析URL的应用程序应该使用什么协议,方案组件必须以一个字母符号开始,由第一个:符号将其与URL的其余部分分隔开。方案名是与大小写无关的。
主机和端口:主机和端口告诉应用程序应该到哪个服务器以及哪个服务器的什么地方能够找到资源。主机组件标示了因特网上能够访问资源的宿主机器,可以用字母表示的域名或者IP地址表示。端口组件表示了,服务器正在监听的网络端口,对下层使用tcp协议的http来说,默认的端口号是80。
用户名和密码组件:会有服务器要求用户输入用户名和密码再访问数据:如 ftp://anonymous:my_password@ftp.prep.ai.mit.edu/pub/gnu
路径:URL的路径组件说明了资源位于服务器的什么地方,它通常很像一个分级的文件系统路径,用 / 将路径组件划分为一些路径段,每个路径段都有自己的参数组件。
参数:参数组件提供了更多的附加信息,以便更好的跟服务器进行交互。它是一个名值对列表,由字符;分隔。例如ftp://prep.ai.edu/pub/gnu;type=d 参数是type,值为d。路径段可以分成若干段,每段都可以有自己的参数。如 www.abc.com/hammers;sal…
查询字符串:在数据库服务中,我们一般使用查询字符串来缩小所请求资源范围的。如 www.abc.com/inventory?i…
片段:比如某个大型的html文件中,你想浏览文档中特定的片段的时候,就可以在url后面加上一个片段,如 www.abc.com/tools.html#…
url:分为绝对的和相对的,相对URL需要在基础URL上解释。
url中的字符:url是可移植的,它要统一的命名因特网上所有的资源,这也就意味着要通过各种不同的协议来传送这些资源,因为不同的协议在传输数据时都会使用不同的机制,所以URL的设计需要考虑到如何安全的传输url。比如传输电子邮件的简单邮件传输协议,所使用的传输方法会剥去一些特定的字符,为了避开这些问题,URL只能使用一些相对较小的,通用的安全字母表中的字符。除此之外,考虑到URL的可读性,一些不可见,不可打印的字符虽然能够穿过邮件程序(空格符),成为可移植的,也不能在URL中使用。考虑到URL完整性,有时候人们可能会希望URL中包含除通用的安全字母表之外的二进制数据或者字符。因此需要一种转义机制,能够将不安全的字符编码为安全字符,再进行传输。编码机制为一个百分号%,后面跟着两个表示字符ASCII码的十六进制数,空格(0x20)%( 0x25 ) ~ ( 0x7E )。另外,在URL中有些字符被保留起来,有着特殊含义,除了将其用于保留用途之外的场合时,要在URL中对其进行编码。如%保留作为编码字符的转译标志,/作为路径组件中分隔路径段的定界符,?保留作为查询字符串定界符使用。
http报文
报文流:HTTP报文是在HTTP应用程序之间发送的数据块,这些数据块以一些文本形式的元信息开头,这些信息描述了报文的内容及含义,后面跟着可选的数据部分,这些报文在客户端、服务器和代理之间流动,术语流入,流出,上游,下游都是用来描述报文方向的。所有的报文都会像下游流动,所有报文的发送者都在接收者上游。
报文的组成部分:对报文进行描述的起始行,包含属性的首部块,以及可选的包含数据的主体部分。
报文的语法:所有的HTTP报文都可以分为请求报文和响应报文两类。
请求报文的格式: <method> <request-URL> <version>
<headers>
<entity-body>
响应报文的格式: <version> <status> <reason-phrase>
<headers>
<entity-body>
注意:版本号不会被当作小数处理,比如HTTP/2.22就比HTTP/2.3的版本要高。
首部:分为五个主要的类型,分别是通用首部、请求首部、响应首部、实体首部、扩展首部。
通用首部:提供了与报文相关的最基本的信息。
| 首部 | 描述 |
|---|---|
| Connection | 允许客户端和服务器指定与请求/响应连接有关的选项 |
| Date | 提供日期和时间标志,说明报文是什么时间创建的。 |
| Transfer-Encoding | 告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式 |
| Via | 显示了报文经过的中间节点(代理,网关) |
| Cache-Control | 用于随报文传送缓存指示 |
请求首部:是只在请求报文中有意义的首部。
| 首部 | 描述 |
|---|---|
| Client-IP | 提供了运行客户端的机器的IP地址。 |
| From | 提供了客户端用户的E-mail地址。 |
| Host | 给出了接受请求的服务器的主机名和端口号。 |
| Referer | 提供了包含当前请求URI的文档的URL。 |
| User-Agent | 将发起请求的应用程序名称告知服务器。 |
| Accept首部 | 为客户端提供了一种将其喜好和能力告知服务器的方式。 |
| Accept | 告诉服务器能够发送哪些媒体类型。 |
| Accept-Charset | 告诉服务器能够发送哪些字符集。 |
| Accept-Charset | 告诉服务器能够发送哪些编码方式。 |
| 条件请求首部 | 客户端希望为请求加上某些限制。 |
| Expect | 允许客户端列出某请求所要求的服务器行为。 |
| If-Match | 如果实体标记与文档当前的实体标记相匹配,就获取这份文档。 |
| If-Modified-Since | 除非在某个指定的日期之后资源被修改过,否则就限制这个请求。 |
| 安全请求首部 | 客户端在获取特定的资源之前,先对自身进行认证。 |
| Authorization | 包含了客户端提供给服务器,以便对其自身进行认证的数据。 |
| Cookie | 客户端用它向服务器传送一个令牌。 |
| Cookie2 | 用来说明请求端支持的cookie版本。 |
| 代理请求首部 | 随着因特网上代理的普遍应用,人们定义了几个首部来协助其更好的工作。 |
| Max-Forward | 在通往源端服务器的路径上,将请求转发给其他代理或网关的最大次数。 |
响应首部:为客户端提供了一些额外信息。
| 首部 | 描述 |
|---|---|
| Age | 从最初创建开始,响应持续时间。 |
| Retry-After | 如果资源不可用的话,在此日期或时间重试。 |
| Warning | 比原因短语中更详细一些的警告报文。 |
| 协商首部 | 服务器可以用他们来传递与可协商资源有关的信息。 |
| Accept-Range | 对此资源来说,服务器可接受的范围类型 |
实体首部: 提供了有关实体及其内容的大量信息.
| 首部 | 描述 |
|---|---|
| Allow | 列出了可以对此实体执行的请求方法。 |
| Location | 告知客户端实体实际上位于何处,用于将接收端定向到资源的位置上去。 |
| Content-Type | 这个主体的对象类型。 |
| Content-Length | 主体的长度或尺寸。 |
| Content-Encoding | 对主体执行的任意编码方式。 |
| 实体缓存首部 | 通用的缓存首部说明了如何或什么时候进行缓存,实体缓存首部提供了与被缓存实体有关的信息。 |
| ETag | 与此实体相关的实体标记。 |
| Expires | 实体不再有效,要从原始的源端再次获取此实体的日期和时间。 |
| Last-Modified | 这个实体最后一次被修改的日期和时间。 |
实体标记:某个特定资源版本的标识符。