websocket不适用proxy_cache_bypass,因其基于http升级后脱离http生命周期,缓存机制完全不介入;应通过独立location块禁用所有缓存指令并显式关闭proxy_cache、proxy_buffering来确保绕过缓存。

缓存绕过本身不会直接导致 WebSocket 断开,但排查过程中若误操作(比如强制刷新、禁用代理、修改 hosts 或临时关闭 CDN/WAF),可能意外暴露底层真实链路中的配置缺陷——而这些缺陷原本被缓存层或中间件“掩盖”了。真正断开的根源,往往藏在绕过之后首次直连暴露出的 Nginx 超时、WAF 拦截、心跳缺失或后端资源限制等问题中。
确认是否真发生了“缓存绕过”
WebSocket 连接不走 HTTP 缓存机制,不存在传统意义上的“浏览器缓存命中/未命中”。所谓“缓存绕过”,实际多指以下行为:
- 前端改用 IP 直连(如
wss://192.168.1.100:8586)跳过 CDN、WAF 或反向代理 - 本地 hosts 绑定源站 IP,绕过 DNS 解析路径上的缓存或安全网关
- 开发者工具 Network 面板勾选 “Disable cache”,但这对 WebSocket 握手请求无效(握手是全新 TCP 连接,不复用 HTTP 缓存逻辑)
绕过之后连接异常?重点查这三处
一旦绕过缓存层后 WebSocket 突然频繁断开(尤其是固定时间点如 60s、300s),说明之前是缓存/WAF 层在“兜底”或“掩盖”问题。此时应立即检查:
-
Nginx 的 proxy_read_timeout 是否仍为默认 60 秒:绕过 WAF 后流量直打 Nginx,若未显式延长该值,空闲连接会在 60 秒后被 Nginx 主动 RST,触发
onclose.code = 1006 -
WAF 是否曾隐式透传 Upgrade 头:某些 WAF(如 Cloudflare 开启 WebSocket 支持后)会自动补全
Connection: upgrade和Upgrade: websocket;绕过后这些头若未由 Nginx 显式设置,服务端收不到合法升级请求,握手失败,表现为“连接瞬间关闭” -
后端服务是否暴露了自身超时限制:例如 Node.js 的
server.timeout、Go 的http.Server.ReadTimeout、PHP Swoole 的heartbeat_idle_time,绕过中间层后这些参数直面客户端,若未调大,也会在固定周期后断连
快速验证:绕过前后对比法
用同一台设备、同一浏览器标签页,在两个状态间切换测试:
-
状态 A(经 WAF/CDN):记录 WebSocket 握手响应码(必须是
101 Switching Protocols)、Upgrade和Connection响应头是否存在、连接稳定时长 -
状态 B(hosts 直连源站):同样抓包看 Network → WebSocket 请求项,对比响应状态、头信息、是否出现
502 Bad Gateway或400 Bad Request,以及 onclose.code 值 - 若状态 A 正常、B 异常,且 B 出现 1006 或握手失败,则问题 90% 出现在 Nginx 配置缺失或后端超时过短
绕过不是解法,而是诊断开关
缓存绕过只是帮你把“被掩盖的问题”拉到前台。它本身不修复任何东西,反而可能让原本被 WAF 心跳保活、Nginx 连接复用或 CDN 协议兼容性处理掩盖的配置缺陷立刻显现。真正要做的,是在绕过确认问题后,回到真实链路中补全关键配置:
- Nginx 中确保有:
proxy_http_version 1.1;、proxy_set_header Upgrade $http_upgrade;、proxy_set_header Connection "upgrade";、proxy_read_timeout 86400; - 后端服务开启应用层心跳(ping/pong),并确保其间隔
- 若使用 WAF,务必开启“WebSocket 协议识别”或添加精准放行规则,而非依赖绕过











