go 的 http.server 默认不支持 http/2 服务端推送,因该特性已被浏览器厂商弃用且从 http/2 规范中移除;自 go 1.22 起 push 方法直接 panic,应改用 link 头 preload 等现代替代方案。

Go 的 http.Server 默认不支持 HTTP/2 服务端推送
HTTP/2 推送(Push)在 Go 标准库中早已被标记为 Deprecated,从 Go 1.22 开始,ResponseWriter.Push 方法直接 panic,错误信息是 "http: no Push support"。这不是配置问题,是标准库主动移除——因为浏览器厂商已全部弃用该特性(Chrome 96+、Firefox 97+、Safari 15.4+ 均禁用),IETF 也明确将其从 HTTP/2 规范中移出。
所以,如果你在查 Push 相关文档或试图调用 w.(http.ResponseWriter).Push,会立刻失败。别折腾 TLS 配置或 Server.TLSConfig,那和推送无关。
想提前加载资源?用 Link: <...> ; rel=preload</...> 替代
现代替代方案是服务端在响应头里写 Link,让浏览器自主决定是否预加载。它兼容 HTTP/1.1 和 HTTP/2,且不依赖服务器推送逻辑。
-
Link头必须是绝对 URL(如/static/app.js要写成https://example.com/static/app.js或带协议相对路径//example.com/static/app.js) - 只对同源资源有效;跨域需确保目标资源支持
CORS且浏览器未因安全策略忽略 - 常见
rel值:preload(强制预加载)、preconnect(预建连接)、dns-prefetch(仅 DNS 查询) - Go 中设置方式简单:
w.Header().Set("Link", `<https://example.com/static/app.js>; rel=preload; as=script`)`</li> </ul> <H3>启用 HTTP/2 本身仍有必要,但和“推送”无关</H3> <p>HTTP/2 的多路复用、头部压缩、服务器流控等优势仍在。Go 默认在 TLS 下启用 HTTP/2(只要 Go ≥ 1.8 + TLS 配置正确),无需额外开关。</p><div class="aritcle_card flexRow"> <div class="artcardd flexRow"> <a class="aritcle_card_img" href="/ai/761" title="Pliny"><img src="https://img.php.cn/upload/ai_manual/001/503/042/68b6db26747b8162.png" alt="Pliny" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a> <div class="aritcle_card_info flexColumn"> <a href="/ai/761" title="Pliny">Pliny</a> <p>创建、分享和重新组合AI应用程序</p> </div> <a href="/ai/761" title="Pliny" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/00968c3c2c15" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">go语言免费学习笔记(深入)</a>”;</p> <p>验证是否生效:</p> <ul> <li>启动服务后,用 <code>curl -I --http2 https://localhost:8443/看响应头是否含HTTP/2 200 - Chrome DevTools → Network → 协议列显示
h2 - 注意:HTTP/2 要求 TLS;纯 HTTP(非 HTTPS)端口无法协商 HTTP/2,
http.ListenAndServe永远走 HTTP/1.1
如果真要模拟“推送效果”,只能靠客户端主动请求 + 缓存协同
没有服务器强制推送,但可以通过组合手段逼近效果:
- 首屏 HTML 响应中内联关键 CSS/JS(减少 RTT)
- 用
Link: rel=preload提前声明后续 JS/CSS,配合as=script/as=style让浏览器优先调度 - 设置合理
Cache-Control(如public, max-age=31536000),使资源可被强缓存,后续页面直接复用 - 避免在 HTML 中用
async或defer延迟关键资源——它们会错失 preload 的早期加载时机
真正的瓶颈往往不在“推不推”,而在资源粒度是否合理、缓存头是否写对、CDN 是否命中。盯着 Push 徒劳调试,不如检查 Link 头有没有拼错 URL、有没有漏掉 as 参数、或者 CDN 把自定义响应头给 strip 了。









