HTTP 进化史:从 1.0 到 3.0

第一次用 56 K「小猫」拨号上网吗?点开一张图片都要等十几秒。二十多年过去,今天的网页动辄上百个资源,却依然能做到秒开。秘诀就藏在 HTTP 协议的三次大升级里。

一、HTTP/1.0

sequenceDiagram rect rgb(191,155,248) 客户端->服务器: TCP三次握手,建立连接 end rect rgb(196,223,252) 客户端->>服务器: 请求 服务器->>客户端: 响应 end rect rgb(191,155,248) 客户端->服务器: TCP四次挥手,销毁连接 end rect rgb(191,155,248) 客户端->服务器: TCP三次握手,建立连接 end rect rgb(196,223,252) 客户端->>服务器: 请求 服务器->>客户端: 响应 end rect rgb(191,155,248) 客户端->服务器: TCP四次挥手,销毁连接 end

痛点:用完即焚的 TCP

  • 每发一次请求,浏览器都要和服务器「握手---挥手」走完全程:
    三次握手 → 发请求 → 收响应 → 四次挥手。
  • 页面里 20 张图片?那就重复 20 次。
  • 更惨的是「队头阻塞」:前一个请求卡住了,后面所有请求都得排队。

结果就是慢、浪费、带宽空转

二、HTTP/1.1

sequenceDiagram rect rgb(191,155,248) 客户端->服务器: TCP三次握手,建立连接 end rect rgb(196,223,252) 客户端->>服务器: 请求 服务器->>客户端: 响应 客户端->>服务器: 请求 服务器->>客户端: 响应 end rect rgb(191,155,248) 客户端->服务器: TCP四次挥手,销毁连接 end

1. 长连接(Keep-Alive)

请求头带上 Connection: keep-alive,TCP 不再用完就关,而是"先别挂电话,我等会儿还有事"。

2. 管道化(Pipelining)

浏览器可以不等上一个响应回来,就连续发多个请求。

可惜服务器必须按顺序回包------一旦某个包慢,后面的响应全部堵死,这就是队头阻塞

3. 曲线救国

为了"并行",前端工程师把图片、CSS、JS 扔到不同域名,浏览器一口气开 6 条 TCP 连接,硬是靠"多开几条车道"缓解堵车。

三、HTTP/2

HTTP/2 不再用文本,而是把所有数据切成二进制帧。每个帧都带一个"车牌号"(流 ID),告诉接收端"我属于哪一次请求"。

核心特性

  • 多路复用
    同一根 TCP 里可以交错跑无数条"流",谁先准备好谁先回,彻底解决队头阻塞。
  • 头部压缩(HPACK)
    把重复的 Cookie、User-Agent 等字段压缩成索引,省掉 50% 以上体积。
  • 服务器推送
    服务端猜你接下来要 app.css,于是提前把帧推过来,浏览器省一次往返。

结果:单连接也能跑满带宽,前端再也不用"域名散列"这种黑魔法。

四、HTTP/3

HTTP/2 再快,也救不了 TCP 的"老寒腿":三次握手慢、拥塞控制保守、任何丢包都会阻塞整个管道。

于是 HTTP/3 直接把底层换成 QUIC ------ 基于 UDP 的可靠传输协议。

QUIC 带来的变化

  • 0-RTT 建链
    以前需要 1.5 ~ 2 个 RTT 才能发数据,QUIC 在首次连接后把参数缓存下来,下次直接发应用数据。
  • 内建多路复用
    每个流独立编号、独立重传,丢包只影响一条流,不再"一人感冒全家吃药"。
  • 连接迁移
    手机从 4G 切到 Wi-Fi,QUIC 的 CID(连接标识)让你"换网不换链",下载继续跑。

五、总结

复制代码
HTTP/1.0  短连接  单车道  堵车
HTTP/1.1  长连接  6 车道  顺序放行
HTTP/2    单 TCP  多车道  无顺序
HTTP/3    单 QUIC 多车道  无顺序 + 丢包不堵车

从"写完就撕"的 1.0,到"拆帧并行"的 2,再到"换引擎"的 3,HTTP 的每一次升级都在回答同一个问题:如何让数据更快、更稳、更安全地到达用户

相关推荐
掘金安东尼3 分钟前
官方:什么是 Vite+?
前端·javascript·vue.js
柒崽4 分钟前
ios移动端浏览器,vh高度和页面实际高度不匹配的解决方案
前端
渣哥20 分钟前
你以为 Bean 只是 new 出来?Spring BeanFactory 背后的秘密让人惊讶
javascript·后端·面试
烛阴29 分钟前
为什么游戏开发者都爱 Lua?零基础快速上手指南
前端·lua
大猫会长38 分钟前
tailwindcss出现could not determine executable to run
前端·tailwindcss
Moonbit43 分钟前
MoonBit Pearls Vol.10:prettyprinter:使用函数组合解决结构化数据打印问题
前端·后端·程序员
533_1 小时前
[css] border 渐变
前端·css
云中雾丽1 小时前
flutter的dart语言和JavaScript的消息循环机制的异同
前端
地方地方1 小时前
Vue依赖注入:provide/inject 问题解析与最佳实践
前端·javascript·面试
云中雾丽1 小时前
dart的继承和消息循环机制
前端