Skip to main content

# HTTP/2 和 HTTP/1.1 的对比

## 相关问题​

- 了解 HTTP/2 吗
- HTTP/1.0、HTTP/1.1 和 HTTP/2 的区别

## 回答关键点​

`队头阻塞` `持久连接` `二进制分帧层` `多路复用` `服务端推送`

HTTP/1.1 相较 HTTP/1.0 的改进和优化：

- 持久连接
- HTTP 管道化
- 分块编码传输
- 新增 Host 头处理
- 更多缓存处理
- 新增更多状态码
- 断点续传、并行下载

HTTP/1.1 的缺点：

- 队头阻塞（Head-of-line blocking）
- 头部冗余
- TCP 连接数限制

HTTP/2 的优点：

- 二进制分帧层
- 多路复用
- Header 压缩
- 服务端推送

## 知识点深入​

### 1. HTTP/1.1​

#### 1.1 相较 HTTP/1.0 的改进和优化​

HTTP/1.1 相比于 HTTP/1.0 的改进和优化主要包含：持久连接、HTTP 管道化请求、分块编码传输、新增 host 头字段、缓存支持、更多状态码等。

持久连接

在 HTTP/1.0 时期，每进行一次 HTTP 通信，都需要经过 TCP 三次握手建立连接。若一个页面引用了多个资源文件，就会极大地增加服务器负担，拉长请求时间，降低用户体验。

HTTP/1.1 中增加了持久连接，可以在一次 TCP 连接中发送和接收多个 HTTP 请求/响应。只要浏览器和服务器没有明确断开连接，那么该 TCP 连接会一直保持下去。

持久连接在 HTTP/1.1 中默认开启（请求头中带有 Connection: keep-alive），若不需要开启持久连接，可以在请求头中加上 Connection: close。

HTTP 管道化

HTTP 管道化是指将多个 HTTP 请求同时发送给服务器的技术，但是响应必须按照请求发出的顺序依次返回。

但是由于 HTTP 管道化仍存在诸多问题：

1. 第一个响应慢仍会阻塞后续响应
2. 服务器为了保证能按序返回需要缓存提前完成的响应而占用更多资源
3. 需要客户端 、代理和服务器都支持管道化

所以目前大部分主流浏览器默认关闭 HTTP 管线化功能。

分块编码传输

在 HTTP/1.1 协议里，允许在响应头中指定 Transfer-Encoding: chunked 标识当前为分块编码传输，可以将内容实体分装成一个个块进行传输。

新增 Host 头处理

在 HTTP/1.0 中认为每台服务器都绑定一个唯一的 IP 地址，因此一台服务器也无法搭建多个 Web 站点。

在 HTTP/1.1 中新增了 host 字段，可以指定请求将要发送到的服务器主机名和端口号。

断点续传、并行下载

在 HTTP/1.1 中，新增了请求头字段 Range 和响应头字段 Content-Range。

前者是用来告知服务器应该返回文件的哪一部分，后者则是用来表示返回的数据片段在整个文件中的位置，可以借助这两个字段实现断点续传和并行下载。

#### 1.2 HTTP/1.1 的缺点​

队头阻塞

虽然在 HTTP1.1 中增加了持久连接，能在一次 TCP 连接中发送和接收多个 HTTP 请求/响应，但是在一个管道中同一时刻只能处理一个请求，所以如果上一个请求未完成，后续的请求都会被阻塞。

头部冗余

HTTP 请求每次都会带上请求头，若此时 cookie 也携带大量数据时，就会使得请求头部变得臃肿。

TCP 连接数限制

浏览器对于同一个域名，只允许同时存在若干个 TCP 连接（根据浏览器内核有所差异），若超过浏览器最大连接数限制，后续请求就会被阻塞。

### 2. HTTP/2​

#### 2.1 HTTP/2 的优点​

二进制分帧层

在 HTTP/1.x 中传输数据使用的是纯文本形式的报文，需要不断地读入字节直到遇到分隔符为止。而 HTTP/2 则是采用二进制编码，将请求和响应数据分割为一个或多个的体积小的帧。

多路复用

HTTP/2 允许在单个 TCP 连接上并行地处理多个请求和响应，真正解决了 HTTP/1.1 的队头阻塞和 TCP 连接数限制问题。

Header 压缩

使用 HPACK 算法来压缩头部内容，包体积缩小，在网络上传输变快。

服务端推送

允许服务端主动向浏览器推送额外的资源，不再是完全被动地响应请求。例如客户端请求 HTML 文件时，服务端可以同时将 JS 和 CSS 文件发送给客户端。

## 参考资料​

1. HPACK: Header Compression for HTTP/2

Loading script...