HTTP 版本

107 阅读4分钟

更详细的版本介绍,请参数 这篇文章

HTTP/1.0

最早的http只是使用在一些较为简单的网页上和网络请求上,所以比较简单,每次请求都打开一个新的TCP链接,收到响应之后立即断开连接。

HTTP/1.1

  • HTTP/1.1 引入了更多的缓存控制策略,如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等
  • HTTP/1.1 允许范围请求,即在请求头中加入Range 头部
  • HTTP/1.1 的请求消息和响应消息都必须包含 Host 头部,以区分同一个物理主机中的不同虚拟主机的域名
  • HTTP/1.1 默认开启持久连接,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。

HTTP/2.0

在 HTTP/2 中,有两个非常重要的概念,分别是帧(frame)和流(stream),理解这两个概念是理解下面多路复用的前提。

帧代表数据传输的最小的单位,每个帧都有序列标识表明该帧属于哪个流,

流也就是多个帧组成的数据流,每个流表示一个请求

这里有个chrome扩展程序,可以方便的查看当前网站的HTTP请求版本(安装后在chrome开发工具-Network-在Name/Size/Time表格头右键选择Procotol,即可查看协议版本)。

新的二进制格式

HTTP/1.x 的解析是基于文本的。基于文本协议的解析存在天然缺陷,文本的表现形式有多样性,要做到全面性考虑的场景必然很多。二进制则不同,只识别0和1的组合。基于这种考虑 HTTP/2.0 的协议解析采用二进制格式,方便且强大。

多路复用

HTTP/2.0 支持多路复用,这是 HTTP/1.1 持久连接的升级版。多路复用,就是在一个 TCP 连接中可以存在多条流,也就是可以发送多个请求,服务端则可以通过帧中的标识知道该帧属于哪个流(即请求),通过重新排序还原请求。

多路复用允许并发的发起多个请求,每个请求及该请求的响应不需要等待其他的请求或响应,避免了线头阻塞问题。这样某个请求任务耗时严重,不会影响到其它连接的正常执行,极大的提高传输性能。

头部压缩

HTTP/1.x 的请求和响应头部带有大量信息,而且每次请求都要重复发送

HTTP/2.0 使用 encoder 来减少需要传输的头部大小,通讯双方各自 cache 一份头部 fields 表,既避免了重复头部的传输,又减小了需要传输的大小。

服务端推送

这里的服务端推送指把客户端所需要的 css/js/img 资源伴随着 index.html 一起发送到客户端,省去了客户端重复请求的步骤(从缓存中取)。

HTTP/3.0

HTTP/2.0 使用了多路复用,一般来说同一域名下只需要使用一个 TCP 连接。但当这个连接中出现了丢包的情况,那就会导致整个 TCP 都要开始等待重传,也就导致了后面的所有数据都被阻塞了。

反而对于 HTTP/1.0 来说,可以开启多个 TCP 连接,出现丢包反倒只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据。 出现包阻塞的原因是因为底层TCP协议导致的问题,但是修改TCP协议是不现实的问题,就像 typeof null === 'object' 一样,修改这个问题会导致出现更多的问题。

既然不能修改你,那就另起一个协议取代你。Google 基于 UDP 协议推出了一个的 QUIC 协议,并且使用在了 HTTP/3 上。

QUIC 基于 UDP,但是 UDP 本身存在不稳定性等诸多问题,所以 QUIC 在 UDP 的基础上新增了很多功能,比如多路复用、0-RTT、使用 TLS/1.3 加密、流量控制、有序交付、重传等等功能。

避免包阻塞

多个流的数据包在TCP连接上传输时,若一个流中的数据包传输出现问题,TCP 需要等待该包重传后,才能继续传输其它流的数据包。但在基于 UDP 的 QUIC 协议中,不同的流之间的数据传输真正实现了相互独立互不干扰,某个流的数据包在出问题需要重传时,并不会对其他流的数据包传输产生影响。

快速重启会话

普通基于tcp的连接,是基于两端的 ip 和端口和协议来建立的。

在网络切换场景,例如手机端切换了无线网,使用 4G 网络,会改变本身的 ip,这就导致 tcp 连接必须重新创建。

而 QUIC 协议使用特有的 UUID 来标记每一次连接,在网络环境发生变化的时候,只要 UUID 不变,就能不需要握手,继续传输数据。

更多