TOP ⬆

HTTP 从 1 到 2 再到 3

当前我们常用的 HTTP 是一种基于TCP 协议栈的协议,因此 HTTP 协议必不可少要受到了 TCP 协议的影响,现在就让我们开始了解 TCP 的特性到底影响了 HTTP 协议的哪些方面?我们从 HTTP 的不足入手,再一步一步从 HTTP0.9 前进到 HTTP3 时代。

HTTP 1

HTTP0.9 是最初的简单版本,在那个时代背景下(1991 年),浏览器还没有得到广泛使用,其主要目的是被用于学术间的交流传输超文本文件,因为需求简单,其甚至都不存在请求头等复杂配置,只需要一个请求行而响应则只需要直接把超文本文件的数据以 ASCII 字节码的形式回传即可,当然,这时候其底层依托的也是 TCP 协议。

到了浏览器开始展露苗头时,我们需要使用 HTTP 协议传输的文件类型就变多了,仅靠一个请求行和响应直接回送数据是远远不够的了,于是 HTTP1.0 应运而生,我们现如今熟悉的 HTTP 协议中的很多内容都是在这个时刻中诞生的。

HTTP1.0 为 HTTP 协议引入了请求头和响应头、状态码、缓存机制(用 If-Modified-Since,Expires 来做为缓存判断的标准),现在请求和响应可以交互了,在简单的网站上我们可以使用 HTTP 协议来传输各种类型的文件,如 CSS 样式表、JS 脚本文件、图像等,我们还可以规定数据的编码、压缩格式等等,这时 HTTP 协议已经具备了雏形。但 HTTP1.0 的缺点也是很明显的,比如:

为了解决这些问题,HTTP1.1 就对其做出了一定的修改和完善:

  1. 丰富状态码,还提供了 100 状态码,这样客户端会预先发送一个带部分请求体的请求,在得到服务器 100 响应后才会正式地发送剩余的完整数据,避免因为服务器拒绝而浪费了太多资源
  2. 增加 HOST 字段,用来标识域名,解决了一个 IP 对应一个域名的问题
  3. 使用 keep-alive 字段保持长连接,让一个 TCP 连接上可以跑多个 HTTP 请求,这样就避免了重复的无效请求还要忍受 TCP 慢启动的折磨
  4. 使用 range 头域、content-range 头来实现文件部分内容传输和断点重传

还增加了 cookie 机制,再引入 Chunk transfer 机制实现了对动态内容的支持,动态内容即传输时并不知道具体的长度,利用最后一个包携带的结束标识判断是否传输完毕,有了这些功能后的 HTTP 协议开始发挥功力,得到了广泛的应用,并沿用至今,但其受 TCP 的影响还有一些不得不面对的大问题:队头阻塞、TCP 慢启动、多条 TCP 连接竞争带宽

HTTP-SPDY优化方案(由 google 强势推出):

  1. 使用多个 Stream 让单条 TCP 上能处理多条 HTTP 请求,还可以设置请求优先级
  2. Header 压缩,因为每条请求都要用到 Header,对其进行压缩能很好节约资源
  3. 使用预推送,在请求 a.html 时服务器可以知道后面可能需要 a.css 和 a.js,则响应上会捎带这些消息
  4. 基于 HTTPS的传输加密

HTTP 2

HTTP2 可以看成是 HTTP-SPDY的进一步升级版本,主要目的是在基于TCP 协议栈的基础上提升 HTTP1.X 的性能,其和SPDY不同的点在于并不强制要求使用HTTPS保证传输的安全性,Header 的压缩算法也不一样。

HTTP2 也是“渐进式”的,兼容 HTTP1.X 版本的,对于不兼容 HTTP2 的浏览器服务器端也是可以通过配置实现自动向下兼容的。但 HTTP2 依托的仍然是 TCP 协议,因此还是会存在队头阻塞的问题,而且由于只存在一条 TCP 连接,在丢包率达到 2%的情形下,HTTP1.1 协议(同一域名 6 条 TCP 连接)的性能要比 HTTP2.0 好!

HTTP 3

HTTP3 是一种颠覆性的协议,因为其底层使用了QUIC(Quick UDP Internet Connection)顾名思义,QUIC 又是一种基于 UDP 的协议,TCP 与 UDP 这两种协议总是被放在一起做比较,QUIC 就是在 UDP 的基础上模拟 TCP,实现了部分 TCP 的功能,这样就能做到在速度和可靠间平衡,其主要的功能有:

结尾

HTTP/TCP 协议是成为一名优秀的前端工程师要深入了解的知识,这篇文章也只是管中窥豹,大概的浏览了一下 HTTP 协议的前世今生,最后展望了一下 HTTP 协议的未来。这里面的每一个知识点都是值得深入学习的,比如 TCP 协议的慢启动、拥塞控制、快重传、快恢复,以这篇文章做起点,我会一点一点地耕耘出与协议栈的相关知识,下篇文章,着眼于 HTTP 协议安全部分的设计。