http1-3应该算是前端面试经典必问TOP10吧,下面结合青训营课程“计算机网络概论”和其他资料整理出各个版本最值得了解的变化。
http0.9
单行协议,只支持GET这一种请求方法,只能传输html(所以叫超文本传输协议)。
http1.x
从左到右分别是http1.0的短连接、http1.1的长连接和流水线模型。
http1.0(1996)
构建可扩展性。
- 开始支持任何类型的文件,常见的有
images, video files, plain text等; - 新增了
http方法,例如head和post; - 增加了状态码
status code标识请求状态; - 增加了
header, 请求头可以携带很多内容;character set support, multi-part types, authorization, caching(Expires, Last-Modified), content encoding and more was included.
问题:
- 每次请求都要建立连接和释放连接,即进行三次握手和四次挥手过程。
http1.1(1999)
标准化协议。
- 新增请求方法:options, put, delete;
- 新增长连接和流水线模型;
- 默认开启长连接,Connection: keep-alive(为 close 是关闭连接);这样不用每个请求都握手挥手;
- 流水线是指在没得到响应时就可以连续发送请求(需要 Content-Length 标识传输的进度或 chunked, 都是避免粘包,一个特殊开启符+消息长度,一个是首位标识符),但受制于 HOL 队头阻塞问题;
问题:
- 队头阻塞:如果有一个请求相应很大,后面有一个小请求,但是由于前面请求的大资源一直没传完,导致后面的请求被阻塞;
- http1.1 的流水线无法多路复用,如果同时请求 js 和 css 文件,数据包返回后 http client 不知道这些数据包是哪一个请求的响应;
http2
专为内容的低延迟传输而设计。
- 二进制协议而不是文本协议(之前是 ASCII 编码,改为二进制编码计算机处理快):
- HTTP 消息由帧构成,例如 Header Frame、Data Frame 和 RST_Frame 等(RST_Frame 可以终止传输,但不关闭连接);
- 每个请求和响应都有一个唯一的流 ID,被分成多个帧发送;
- 多路复用
- 通过单个连接进行多个异步 HTTP 请求;
- 使用帧和流来进行请求和响应,所有流都通过同一连接异步发送,通过流 ID 来区分数据包所属流,解决队头阻塞问题;
- 连接、帧和流之间的关系:一个连接中可以有多个流,一个流就是一个资源的请求数据包,流由多个帧构成。
- 使用 HPACK 进行头压缩(之前都是对 body 采用 gzip 等压缩,头部重复传了很多冗余字段,)
- 静态字典;
- 动态字典;
- Huffman 编码(压缩算法)
- 服务器推送Server Push - 单个请求的多个响应
- 主动推送内容给 client,通过
PUSH_PROMISE帧;主动推送采用奇数的 streamID;
- 主动推送内容给 client,通过
- 支持制定请求优先级;
- 安全,默认开启https;
小林coding,http2介绍的很好,推荐。
问题:
- TCP 层面的阻塞问题。由于 TCP 的可靠性,按序传输,如果main.js的包丢了,即使style.css的所有包都在main.js包后面,都到了,但还是需要重传main.js的包,导致style.css被阻塞。
- 需要 3RTT(Round-Trip Time)启动;(三次握手+TLS 四次握手,http 第三次 ack 和 TLS 第一次 hello 可以同时发,总共是三个来回;)启动时间长;
http3
解决 http2 的问题,上述的问题是由于 TCP 的设计原因,http 层面已经无法改进了;
为此,提出了一个运输层协议--QUIC协议。
QUIC
QUIC, Quick UDP Internet Connection;基于 UDP 提出了 QUIC 协议,和 TCP/UDP 一样工作在传输层,在 UDP 的基础上增加了拥塞控制和超时重传等可靠性保证机制,并将 tls 加密集成进来,可以达到初次 1RTT,二次 0RTT 的启动速度提升。