HTTP/1.0、HTTP/1.1 和 HTTP/2:版本升级到底改了什么
围绕HTTP 版本章节,按连接复用、缓存、Host、Range、chunked、二进制帧、多路复用和头部压缩讲清 HTTP 版本演进。
相关工具
别把 HTTP 版本只背成时间线
HTTP/1.0、HTTP/1.1、HTTP/2 的区别,经常被整理成一张表:长连接、缓存、Host、多路复用、Header 压缩。表格能帮你记关键词,但真正理解时,最好把它放回浏览器加载页面的场景里。
打开一个网页,不只请求 HTML。浏览器还要继续请求 CSS、JavaScript、图片、字体、接口数据。资源越多,连接建立、请求排队、头部重复、带宽浪费的问题就越明显。HTTP 版本升级,很多地方都是在解决这些具体问题。
文中把 HTTP/1.0 和 HTTP/1.1 的差异放在长连接、缓存、管道化、Host、状态码和带宽优化上,又把 HTTP/2 的变化概括为二进制格式、多路复用、Header 压缩和服务端推送。这篇就按这个顺序讲,不把版本号讲成孤立概念。

从短连接到长连接,再到二进制帧和多路复用,HTTP 的升级主要围绕传输效率展开。
HTTP/1.0:一次请求常常对应一次连接
HTTP/1.0 默认是短连接。客户端每发起一次请求,通常都要建立一个 TCP 连接;请求和响应结束后,连接就断开。这个模型很直接,也容易实现,但在网页资源越来越多之后,问题会变得明显。
建立 TCP 连接不是零成本。三次握手要花时间,连接关闭也要处理状态。如果一个页面有几十个静态资源,而每个资源都重新建连,连接开销会反复出现。用户感觉到的结果,就是页面加载慢,服务器也要处理更多连接。
HTTP/1.0 也能做缓存,但手段相对简单。文中提到,HTTP/1.0 主要使用 `If-Modified-Since` 和 `Expires` 做缓存判断。也就是说,它更多依赖修改时间和过期时间,控制能力没有后来的 HTTP/1.1 丰富。
HTTP/1.1:Keep-Alive 让连接可以复用
HTTP/1.1 一个很重要的变化,是默认支持长连接,也常被叫作 Keep-Alive。只要客户端或服务端没有明确提出断开,同一个 TCP 连接就可以继续传输多个 HTTP 请求和响应。
这会明显减少连接建立的开销。比如浏览器已经通过一个 TCP 连接拿到了 HTML,后续再请求 CSS、脚本或图片时,可以继续复用这条连接,而不是每次都重新握手。对于有大量静态资源的页面,这个改动很实用。
当然,长连接也不是无限占着不放。服务器会设置空闲超时、最大请求数等策略,避免连接资源被长期占用。理解 Keep-Alive 时,不要把它想成永不关闭的连接,它只是让连接在合理时间内复用。
缓存控制也从粗到细
上一篇讲 HTTP 缓存时已经提到,HTTP/1.0 主要依赖 `Expires` 和 `If-Modified-Since`,HTTP/1.1 引入了更多缓存控制字段,比如 `Cache-Control`、`ETag`、`If-None-Match`。文中也把缓存作为 HTTP/1.0 和 HTTP/1.1 的重要区别。
`Cache-Control` 可以表达更细的策略,比如 `max-age`、`no-cache`、`no-store`、`public`、`private`。`ETag` 则用资源指纹判断内容有没有变化,比单纯看修改时间更准确。
这类变化看起来只是多了几个请求头,背后其实是浏览器、代理服务器、CDN 和源站之间的协作变细了。缓存越精确,就越能减少不必要的下载,同时降低拿到旧资源的概率。
Host 字段让一个 IP 可以放多个站点
HTTP/1.1 增加并强化了 `Host` 字段。它告诉服务器:这次请求访问的是哪个域名和端口。这个字段现在太常见了,以至于很多人会忽略它的重要性。
没有 Host 时,一个服务器 IP 上同时托管多个域名会很麻烦。服务器只看到连接打到了自己的 IP,却不知道客户端想访问 `a.example.com` 还是 `b.example.com`。有了 Host,同一个 IP 可以根据域名区分不同站点,也就是常说的虚拟主机能力。
排查线上问题时,Host 也值得看。请求到了同一个网关或同一个反向代理,如果 Host 不对,可能会被路由到错误站点,返回 404、证书不匹配,或者进入完全不同的服务。
Range 和 206:别每次都传完整文件
文中提到 HTTP/1.1 在请求头引入了 `Range`,允许客户端只请求资源的一部分,服务器返回 `206 Partial Content`。这解决的是带宽浪费问题。
最容易理解的场景是视频拖动和断点续传。用户不一定要从头下载完整文件,他可能只需要某一段。客户端带上 Range,服务器就可以只返回指定范围的数据。这样既节省带宽,也让大文件体验更好。
这也解释了为什么状态码里要单独记 206。它不是普通 200 的别名,而是告诉客户端:服务器成功返回了部分内容。下载工具、视频播放器、对象存储服务里都经常能看到它。
chunked:内容长度未知时也能边生成边传
HTTP/1.1 还支持分块传输编码,也就是 `chunked`。文中写到,它允许响应数据分块,利于传输大文件。更准确地说,当服务器一开始不知道完整响应体长度,或者希望边生成边发送时,chunked 很有用。
普通响应里常见 `Content-Length`,客户端知道后面会收到多少字节。但有些响应是动态生成的,比如实时导出、流式日志、边查边返回的数据。服务器不一定等全部内容准备好再发,可以把响应拆成一个个 chunk。
这类能力让 HTTP/1.1 不只是“能复用连接”,也更适合处理动态内容和大内容。对使用者来说,看到没有 Content-Length、使用 Transfer-Encoding: chunked,不要马上判断异常,它可能是服务端有意采用的传输方式。
HTTP/1.1 管道化:能并着发,但没彻底解决排队
HTTP/1.1 的管道化允许客户端在不等待前一个响应返回的情况下,继续发送多个请求。听起来很像并发,但它有一个限制:响应必须按照请求发出的顺序依次返回。
这就容易出现队头阻塞。假设请求 A 很慢,请求 B 和 C 即使服务端已经处理完,也要排在 A 后面返回。结果是连接看起来被复用了,请求也提前发出去了,但慢请求仍然会拖住后面的响应。
这也是为什么 HTTP/2 要继续改。HTTP/1.1 的长连接减少了建连成本,管道化试图提高传输效率,但应用层的顺序返回限制还在,页面资源多时仍然不够顺滑。

HTTP/1.1 响应仍按顺序返回;HTTP/2 把请求拆成帧,通过 Stream ID 重新归属。
HTTP/2:从文本报文变成二进制帧
HTTP/1.x 的报文是文本格式。文本格式直观,抓包时也容易读,但解析方式多样,边界、空格、大小写等细节都可能带来实现复杂度。文中提到,HTTP/2 采用新的二进制格式,只认 0 和 1,解析更高效,健壮性也更好。
HTTP/2 并没有推翻 HTTP 的语义。请求方法、状态码、Header 这些概念还在,只是底层传输格式变了。可以理解为:上层还是 HTTP,那些 GET、POST、200、404 继续存在;下层把消息拆成更容易管理的二进制帧。
这个变化给多路复用打了基础。请求和响应不再是一整段文本按顺序塞进连接里,而是拆成帧,每个帧带着归属信息,接收端再按标识重新组装。
多路复用:一个连接里同时跑多个请求
HTTP/2 的多路复用,是它最常被提到的特性。文中描述为连接共享:一个请求对应一个 ID,每个连接可以有多个请求,接收方根据请求 ID 把数据归属到不同请求中。
这就解决了 HTTP/1.1 管道化里响应必须按顺序返回的问题。请求 A、B、C 可以被拆成不同 Stream 的帧,在同一个 TCP 连接里交错传输。哪个请求先准备好,相关帧就可以先回来,接收端再按 Stream ID 拼回对应响应。
不过也要注意,HTTP/2 解决的是 HTTP 层面的队头阻塞。在底层如果还是 TCP,一个 TCP 包丢了,后面的字节流仍然会受到影响。这个问题会引出 HTTP/3 和 QUIC,后面可以单独讲。
Header 压缩:别每次都重复发一大堆头
HTTP 请求头里有很多重复字段,比如 Cookie、User-Agent、Accept、Authorization。HTTP/1.x 每次请求都要重复发送这些 Header,资源多时会浪费不少带宽。
HTTP/2 引入 Header 压缩。文中说,通信双方会各自缓存一份 header 字段表,通过 encoder 减少 header 大小。简单讲,就是重复出现的字段不必每次都原样传一遍,可以用更短的索引或编码表示。
这对接口密集、Cookie 很长、资源请求很多的页面很有意义。用户未必直接感知到“Header 压缩”四个字,但它会减少网络传输里的冗余。
服务端推送:概念好懂,但别过度神化
文中还提到 HTTP/2 的服务端推送:把客户端可能需要的静态资源,伴随 `index.html` 一起发送给客户端,省掉客户端再次请求的步骤。直觉上,这很像服务器提前把 CSS、脚本送过来。
这个能力的目标是减少往返等待。浏览器还没解析到某个资源引用时,服务器就猜到它需要,并提前推送。理想情况下,页面加载会更快。
但实际工程里,推送并不总是好用。服务器猜错了会浪费带宽,浏览器缓存里已有资源时也可能重复传输。所以理解它时,把它当作 HTTP/2 的一个能力即可,不要把它当成所有性能问题的答案。
面试和排查时怎么讲才稳
回答 HTTP 版本区别,可以先从问题说起:HTTP/1.0 短连接开销大;HTTP/1.1 默认长连接,增加缓存控制、Host、Range、chunked,并支持管道化;HTTP/2 改用二进制帧,支持多路复用和 Header 压缩,让同一连接承载多个并发请求。
排查时也可以顺着版本特性看。连接反复建立,先看是否复用连接;缓存不符合预期,看 Cache-Control、ETag、Last-Modified;下载大文件或视频拖动异常,看 Range 和 206;接口请求很多、头部很大,看是否使用 HTTP/2 以及 Header 压缩是否生效。
这样讲比单纯背“HTTP/2 有多路复用”更有用。版本升级不是为了多几个术语,而是在解决真实网页访问里的连接成本、重复传输、请求排队和头部冗余。
常见问题
HTTP/1.1 的长连接是不是永远不断开?
不是。Keep-Alive 只是允许连接复用,服务端仍会按空闲时间、请求数量或资源压力关闭连接。
HTTP/2 是否完全解决队头阻塞?
它解决了 HTTP 层面的队头阻塞,但如果底层仍基于 TCP,TCP 丢包造成的阻塞仍可能影响同一连接上的多个流。
HTTP/2 还用 GET、POST、状态码这些概念吗?
还用。HTTP/2 改的是底层表示和传输方式,HTTP 语义仍然保留,请求方法、状态码、Header 这些概念都还在。