要让 WebSocket 在 Nginx 反向代理后稳定运行,必须显式透传 Upgrade 和 Connection 头、禁用缓冲、调大超时时间,并由后端控制 CORS 响应头,最后通过请求头、状态码和错误日志三方面验证。

要让 WebSocket 在 Nginx 反向代理后稳定运行,关键不是“加个头就行”,而是确保协议升级不被截断、连接不被超时中断、帧传输不被缓冲干扰。Nginx 本身支持 WebSocket,但默认配置完全不适用,必须针对性调整。
透传协议升级请求头
WebSocket 握手依赖两个逐跳(hop-by-hop)HTTP 头:Upgrade 和 Connection。Nginx 默认会丢弃它们,必须显式转发:
- proxy_http_version 1.1; —— HTTP/1.0 不支持 Upgrade,必须强制启用 1.1
-
proxy_set_header Upgrade $http_upgrade; —— 将客户端原始的
Upgrade: websocket值原样传给后端 -
proxy_set_header Connection "upgrade"; —— 注意是固定字符串
"upgrade",不是变量;因为 Connection 是逐跳头,不能继承客户端值(如 keep-alive)
防止长连接被主动断开
WebSocket 是全双工长连接,而 Nginx 默认超时和缓冲策略专为短连接设计,极易导致空闲断连或帧延迟:
- proxy_read_timeout 86400; —— 设为 24 小时,避免空闲期被关闭(可按业务需要调低,但不宜低于 3600)
- proxy_send_timeout 86400; —— 同样设为大值,保障服务端心跳或响应能发出
- proxy_buffering off; —— 关闭响应缓冲,防止 WebSocket 帧被暂存、粘包或延迟
- 不配置任何
proxy_cache_*指令 —— WebSocket 消息不可缓存,启用即失败
跨域与安全头由后端控制
浏览器只在 WebSocket 握手阶段(HTTP → 101 Switching Protocols)校验 CORS,且仅检查响应头。这个环节完全由后端决定:
- 不要在 Nginx 的 location 中加
add_header Access-Control-Allow-Origin "*";—— 这对 101 响应无效,还可能覆盖后端正确返回的 CORS 头 - 确保后端在 101 响应中返回
Access-Control-Allow-Origin、Access-Control-Allow-Credentials等头 - Nginx 默认透传这些响应头,无需额外操作;如需确认,可保留
proxy_pass_request_headers on;(默认已开启)
验证配置是否生效
改完配置别急着上线,先通过三方面快速验证:
- 用浏览器开发者工具查看 WebSocket 请求的请求头,确认含
Upgrade: websocket和Connection: upgrade - 检查响应状态码是否为 101 Switching Protocols,不是 200、502 或其他
- 翻看 Nginx
error.log,不应出现upstream prematurely closed connection或client closed connection类报错











