海树

我心有猛虎 细嗅蔷薇香

Owen Lee's avatar Owen Lee

计算机网络面试(12)HTTP 各版本差异

前言

前面几篇文章分别介绍了 HTTP 的基础知识、HTTP 的缓存机制、HTTP 和 HTTPS 的联系与区别。这篇文章来介绍一下,HTTP 从诞生到现在,各个版本之间的差异。

我们知道,HTTP 协议是一个基于 TCP 协议的应用层协议,它不涉及数据包的传输,主要规定了客户端和服务器之间的通信格式。

HTTP/0.9

HTTP 最早的版本是 1991 年的 0.9 版,只有一种请求方式 GET。并且服务器只能响应 HTML 格式的数据。

HTTP/1.0

1996年,HTTP/1.0 发布,内容大大增加。

相比于 0.9 版:

  1. 可以发送任意格式的数据,不仅可以传输文字,还可以传输图像、视频、二进制文件等。
  2. 除了 GET 请求方式,还加入了 POST、HEAD 请求方式。
  3. 请求和响应的格式改变,除了数据部分,每次通信必须包含头信息。
  4. 其他的新增功能还包括状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。

缺点:

HTTP/1.0 的主要缺点是,每个 TCP 连接只能发送一个请求,发送数据完毕,连接就关闭了,如果还要请求其他资源,就必须重新建立连接。

TCP 建立连接成本很高,因为需要客户端和服务器三次握手,并且开始时发送速率较慢(慢启动)。所以,HTTP 1.0 版本的性能比较差。随着网页加载的外部资源越来越多,这个问题就愈发突出了。

为了解决这个问题,有些浏览器在请求时,用了一个非标准的 Connection 字段。

Connection: keep-alive

这个字段要求服务器不要关闭 TCP 连接,以便其他请求复用,服务器同样响应这个字段。这样一个可以复用的 TCP 连接就建立了,直到客户端或服务器主动关闭连接。

HTTP/1.1

1997 年,HTTP/1.1 版本发布,它进一步完善了 HTTP 协议,直到现在还是最流行的版本。

相比于 1.0 版:

  1. HTTP1.1 最大变化是默认支持长连接。即 TCP 连接默认不关闭,可以被多个请求复用,不用声明 Connection: keep-alive。
  2. 管道机制,即在同一个 TCP 连接中,客户端可以同时发送多个请求,进一步改进了 HTTP 协议的效率。

举例来说,客户端需要请求两个资源。以前的做法是,在同一个 TCP 连接里面,先发送 A 请求,然后等待服务器做出回应,收到后再发出 B 请求。管道机制则是允许浏览器同时发出 A 请求和 B 请求,但是服务器还是按照顺序,先回应 A 请求,完成后再回应 B 请求。

  1. 增加了 PUT、PATCH、OPTIONS、DELETE 等请求方式。
  2. 客户端请求的头信息增加了 Host 字段,用来指定服务器的域名。
Host:www.example.com

有了 Host 字段,就可以将请求发往同一台服务器上的不同网站,为虚拟主机的兴起打下了基础。

缺点:

虽然 1.1 版允许复用 TCP 连接,但是同一个 TCP 连接里面,所有的数据通信是按次序进行的。服务器只有处理完一个回应,才会进行下一个回应。要是前面的回应特别慢,后面就会有许多请求排队等着。这称为「队头堵塞」(Head-of-line blocking)。

HTTP/2.0

HTTP2.0 相对于 HTTP1.x 来说提升是巨大的,主要有以下几点:

二进制格式:HTTP1.x 是文本协议,而 HTTP2.0 是以二进制帧为基本单位,是一个二进制协议,一帧中除了包含数据外同时还包含该帧的标识:Stream Identifier,即标识了该帧属于哪个request,使得网络传输变得十分灵活。

多路复用:一个很大的改进,原先 HTTP1.x 一个连接一个请求的情况有比较大的局限性,也引发了很多问题,如建立多个连接的消耗以及效率问题。

HTTP1.x 为了解决效率问题,可能会尽量多的发起并发的请求去加载资源,然而浏览器对于同一域名下的并发请求有限制,而优化的手段一般是将请求的资源放到不同的域名下来突破这种限制。

而 HTTP2.0 支持的多路复用可以很好的解决这个问题,多个请求共用一个 TCP 连接,多个请求可以同时在这个 TCP 连接上并发,一个是解决了建立多个 TCP 连接的消耗问题,一个也解决了效率的问题。那么是什么原理支撑多个请求可以在一个 TCP 连接上并发呢?基本原理就是上面的二进制分帧,因为每一帧都有一个身份标识,所以多个请求的不同帧可以并发的无序发送出去,在服务端会根据每一帧的身份标识,将其整理到对应的 request 中。

header头部压缩:HTTP2.0 使用 HPACK 算法对 header 的数据进行压缩,减少请求的大小,减少流量消耗,提高效率。因为之前存在一个问题是,每次请求都要带上 header,而这个 header 中的数据通常是不变的。

支持服务端推送:HTTP/2.0 允许服务器未经请求,主动向客户端发送资源,这叫做服务器推送。意思是说,当我们对支持 HTTP2.0 的服务器请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取。这种方式非常合适加载静态资源。

服务器端推送的这些资源其实存在客户端的某处地方,客户端直接从本地加载这些资源就可以了,不用走网络,速度自然是快很多的。

参考资料

HTTP 协议入门-阮一峰

Android网络系列(一):关于计算机网络的一些基础

HTTP1.0 HTTP 1.1 HTTP 2.0主要区别

浅析HTTP/2的多路复用