HTTP 协议版本回顾
HTTP 1.0/1.1 的差别、SPDY、HTTP 2 的多路复用 / 表头压缩 / 服务端推送,以及多路复用 vs 长连接。
~/posts/http-versions $ cat post.md
HTTP 1 与 2
目前我们最常见到的是 HTTP 1.1 和 HTTP 2。既然 1.1 还在被广泛使用,那就先说 HTTP 1 和 HTTP 1.1 的区别。
HTTP 1.1 相对 1.0 的改进
- 更丰富的基于 Entity 的缓存控制——从
If-Modified-Since、Expires这种 “从某时刻起” 的形式,扩展到If-Unmodified-Since、If-Match、If-None-Match这种更贴近缓存语义的标签。 - 支持断点续传:对二进制资源可以请求一个 byte range(对应的 header 名也叫
Range)。 Host头:同一个 IP 地址可以承载多个 Host。- 长连接:
Connection: keep-alive。
SPDY
HTTP 2 普及之后,SPDY 的实用价值已经不高。但既然 HTTP 2 几乎是 SPDY 的后继,先说一下 SPDY 是什么。
SPDY 由 Chrome 团队提出,作用在应用层 HTTP 和传输层 TCP 之间(按 OSI 分层我倾向于把它放到会话层,但它又在 SSL/表示层之下)。它优雅地实现了多路复用——这个能力后来被 HTTP 2 吸收——同时给浏览器带来了较强的缓存能力。
SPDY 支持服务端推送:你请求 index.html 时,服务器主动把 bundle.js 和 style.css 推到浏览器的 SPDY 缓存里。后续请求这些文件时直接命中缓存。
补充:上面括号里的 “SSL 层之下” 是真的——SPDY 只支持 HTTPS。
HTTP 2
HTTP 2 在规范上允许明文传输——相对 SPDY 是一项进步。但浏览器从来不严格遵守规范,主流浏览器仍然只接受 HTTPS 上的 HTTP 2。
HTTP 2 上多路复用可以放心用。还有一项实用功能是表头压缩——SPDY 也支持,但毕竟不是规范的一部分。
表头压缩的机制其实很简单:客户端和服务端各持有一份相同符号的对照表,传输时只发送编号,对方按表翻译回来。这件事和”是不是规范”关系大,是因为对照表的内容和编号方式需要双方约定,不写进规范的话谁也没法预先准备好。
“多路复用” 不是早就有了吗
提出这个问题的话,多半是把多路复用和长连接两件事混了。
- 长连接:TCP 连接建立后不立即断开,可以连续发送多个请求/响应。
- 多路复用:在同一条 TCP 连接上可以并发发起多个请求。
两者不冲突,反而互相增强。同一个网站的请求路径对比:
- 无长连接
- TCP 开启
- 请求 index.html → 收到
- TCP 关闭
- TCP 开启
- …
- 长连接
- TCP 开启
- 请求 index.html → 收到
- 请求 bundle.js → 收到
- 请求 style.css → 收到
- …
- 多路复用
- TCP 开启
- 请求 index.html → 收到
- 同时请求 bundle.js、style.css、logo.png
- 各自陆续到达
- …
可以直观看到多路复用对资源密集页面的提速。
这和服务端推送是同一件事吗
不是,服务端推送与多路复用并不冲突。
服务端推送的意思是:你请求了 index.html,但服务器知道(如果你不是爬虫)大概率还会请求 bundle.js、style.css,那干脆主动一并发过去。
HTTP 2 与 SPDY 一脉相承,自然也支持这一点。