本章将针对 HTTP 协议结构进行讲解,主要使用 HTTP/1.1 版本。学完这章,想必大家就能理解 HTTP 协议的基础了。
2.1、HTTP 协议用于客户端和服务端之间的通信
HTTP 协议和 TCP/IP 协议族中众多的协议相同,用于客户端和服务器端互相通信。请求访问资源或则图片等一方叫做客户端,而提供资源的一方叫做服务器端。
2.2、通过请求和响应交换的方式达成通信
HTTP 协议规定,请求从客户端发出,最后服务端响应该请求并返回结果。
请求报文组成结构
请求报文是由请求方法、请求 URI、协议版本、请求头部字段和内容实体构成。
响应报文组成结构
响应报文基本是由协议版本、状态码、状态码解释短语、响应头部字段和实体主体。
2.3、HTTP 是不保存状态的协议
HTTP 是一种不保存状态的协议,即无状态协议。HTTP 协议自身不对请求和响应之间的通信状态做任何保存。这是为了更快的处理更多的事务,确保协议的可伸缩性。
无状态性缺陷:无法记录用户此时的状态,比如是否已登录。
解决方式:对此引入了 Cookie 技术,从而实现请求和响应之间通信间的通信状态保存。
2.4、告知服务器意图的 HTTP 请求方法
下面介绍 HTTP 1.1 相关请求方法
GET:获取资源
GET 方法用来请求访问已被 URI 识别的资源。指定的资源服务器解析后返回响应内容。
使用 GET 方法的请求,响应例子。
POST:传输实体主体
POST 方法用来传输实体的主体。虽然 GET 方法也可以传输实体的主体,但是一般不用 GET 方法进行传输,而是用 POST 方法。虽然 POST 和 GET 方法的功能比较相似,但是 POST 一般不是为了获取资源服务器上的某个资源,而是为了告知资源服务器某些信息,比如:表单数据。
使用 POST 方法请求,响应例子。
PUT:传输文件
PUT 方法用来传输文件。要求在请求报文的主体中包含文件内容,然后保存到请求指 URI 指定的位置上。但是,由于 http 1.1协议的 PUT 方法自身不具备验证机制,这就意味着任何人都可以上传文件,存在安全性能隐患。因此,一般的 Web 网站不使用该方法或者资源服务器直接禁止此方法使用。
使用 PUT 方法的请求,响应例子。
HEAD:获得报文首部
HEAD 方法和 GET 方法一样,只是不返回报文主体部分(获取响应的头部信息)。用于确认 URI 的有效性及其在资源服务器所指定资源更新的时间日期等。
使用 HAED 方法的请求、响应例子。
DELETE:删除文件
DELETE 方法用来删除文件,是与 PUT 相反的方法。DELETE 方法按请求 URI 删除资源浏览器指定资源。但是,同 PUT 方法一样,方法自身没有验证机制。因此,一般的 Web 网站也不使用 DELETE 方法。
使用 DELETE 方法的请求、响应例子。
OPTIONS:询问支持的方法
OPTIONS 方法是用来查询针对请求 URI 指定的资源支持的方法。
使用 OPTIONS 方法的请求,响应例子。
2.5、持久连接节省通信量
在 http 初始版本中,每进行一次通信就要断开一次 TCP 连接。
在当年的通信情况下,因为都是些容量很小的文本传输,即使这样也没什么太大的影响。但是随着 http 的普及,文档中包含大量图片等资源的情况也越来越多。因此这样会造成很多无所谓的 TCP 连接的建立和断开,增加通信量的开销。
持久连接
为了解决上述 TCP 频繁连接问题,http/1.1 和一部分的 http/1.0 想出了持久连接(HTTP Persistent Connections,也称 HTTP keep-alive 或 HTTP connections reuse)的方法。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。
持久化连接的好处在于减少了 TCP 连接的重复建立和断开所造成的资源香的额外开销,减轻了服务器的负载。另外,减少开销的那部分时间,使 HTTP 请求和响应能够更早的结束,这样同时也使 web 页面显示速度也就相应的提高了。
管线化
持久化连接使得多数请求以管线化的方式发送成为了可能。以前发送请求后需要等待并接受,才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。这样就能够做到同时并行发送多个请求,而不需要一个一个的等待响应再发送了。
比如,当请求一个包含10张图片的 HTML Web 页面,与挨个连接相比,用持久化连接可以让请求更快的结束。而管线化技术则比持久连接还要快。请求数量越多,时间差异越明显。
2.6、使用 Cookie 的状态管理
HTTP 是无状态协议,它不对之前发生过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。
假设要求登录认证的 Web 页面本身无法进行状态的管理(不记录已登录的状态),那么每次跳转新页面不是要再次登录,就是要每次请求报文中附加参数来管理登录状态。
不可否认,无状态协议当然也有它的优点。由于不必保存状态,自然可以减少服务器的 CPU 及内存资源的消耗。从另一侧面来说,也正是 HTTP 协议本身是非常简单的,所以才会被应用在各种场景里。
为了既要保留协议无状态这个特性,又要解决通信状态的保存管理,于是就引入了 Cookie 技术。Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的通信状态。
Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文头部字段中添加 Cookie 字段,值为 Set-Cookie 字段值,并发送给服务器。
服务器发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比在服务器上的记录,最后得到之前的状态信息。
上图展示了发生 Cookie 交互的情景,HTTP 请求报文和响应报文的内容如下。