HTTP/2的server push不能替代WebSocket,因为它仅在客户端发起请求后被动推送相关静态资源,不支持服务端任意时间、任意内容、主动向应用层发送业务消息;而WebSocket建立后支持全双工、低开销、真正的服务端主动推送。

HTTP/2 的 server push 不能替代 WebSocket,哪怕你启用了 http2 并配置了推送资源,也解决不了“服务端主动发业务消息”这件事。
为什么 server push 不是真正的服务端推送?
HTTP/2 的推送本质上仍是请求驱动的:客户端必须先发一个 GET /index.html 请求,服务器才能顺带 PUSH_PROMISE 一张 /logo.png 或 /app.js。它只推“与该请求语义相关”的静态资源,且一旦客户端已缓存,服务器就不得再推(浏览器会直接 RST_STREAM)。它不支持任意时间、任意内容、任意目标连接的业务数据下发。
常见错误现象包括:
- 在 Chrome DevTools 的 Network 面板里看到
push标记,误以为能用来发聊天消息 - 用
fetch()触发一次请求后,期待后续所有消息都靠 push 自动到达 —— 实际上后续消息根本不会来 - 尝试在 Express/Koa 中调用
res.push()发送 JSON 数据,结果被忽略或报错(Node.js 的http2模块仅支持推送file或stream,不接受任意 payload)
WebSocket 连接建立后,通信完全脱离 HTTP 协议栈
WebSocket 握手虽走 HTTP(Upgrade: websocket),但一旦 101 Switching Protocols 返回,后续所有帧都是二进制或文本帧,不再有 HTTP 头、状态码、方法、路径等概念。浏览器的 WebSocket 对象发 socket.send('{"type":"msg"}'),服务端收到的就是原始字符串或 ArrayBuffer,中间不经过任何 HTTP 解析。
HISUI 前端框架基础开发指南。HISUI 是基于 easyui 二次开发的 jQuery UI 组件库,专为医疗信息系统设计。当涉及 HISUI 组件开发、jQuery easyui 表格/表单/布局/窗口、医疗系统前端页面编写时使用此 skill。 涵盖 40 个组件的官方文档参考,支持声明式与编程式两种初始化方式,提供 $cm/$m 数据访问方法。
立即学习“前端免费学习笔记(深入)”;
这意味着:
- 服务端可以随时调用
ws.send()向任意已连接的客户端发消息,无需等待客户端请求 - 客户端监听
socket.onmessage就能收,不用轮询、不用重连、不触发 CORS 预检(只要握手时通过) - 连接保持期间,单次消息开销只有 2–14 字节帧头(取决于长度),远低于 HTTP/2 的 HEADERS + DATA 帧组合
- 注意:Nginx 默认会关闭空闲 WebSocket 连接(60s timeout),需显式配置
proxy_read_timeout 300;等参数
前端选型时真正要问的三个问题
别纠结“哪个协议更新”,直接看场景:
- 是否需要服务端在任意时刻主动通知客户端?→ 是 → 选
WebSocket - 是否只是想更快加载 JS/CSS/图片,减少 RTT?→ 是 → 用
http2+preload/preconnect,别碰server push(现代浏览器已弱化支持) - 是否已有大量基于
fetch+JSON的 API,仅需轻微增强实时性(如订单状态变更提醒)?→ 可考虑EventSource(SSE),它比 WebSocket 更轻、自动重连、天然兼容 HTTP 缓存,但只支持服务端→客户端单向
容易被忽略的一点:WebSocket 连接失败时,onerror 不会告诉你具体原因(比如被代理切断、TLS 握手失败、防火墙拦截),只能靠 onclose 的 event.code 和日志排查;而 HTTP/2 的错误(如 REFUSED_STREAM)至少能在 chrome://net-internals 里看到帧级细节。

















