Nginx 1.3.13+ 原生支持 WebSocket 反向代理,但默认配置完全不生效;必须显式设置 proxy_http_version 1.1、透传 Upgrade 和 Connection 头、关闭缓冲、调大超时,否则握手失败或连接被静默中断。

要让 Nginx 的 HTTP 代理正确转发 WebSocket 握手请求,关键不是“自动支持”,而是显式参与并透传协议升级过程。Nginx 1.3.13+ 原生具备能力,但默认配置完全不生效——漏掉任一必要项,都会导致前端报 WebSocket handshake error 或连接几秒后静默断开。
必须设置的三个核心头字段
WebSocket 握手依赖 HTTP/1.1 的 Upgrade 机制,而 Upgrade 和 Connection 是逐跳(hop-by-hop)头,Nginx 默认会过滤掉它们。需在 location 块中明确配置:
- proxy_http_version 1.1:强制使用 HTTP/1.1 协议;HTTP/1.0 不支持 Upgrade,设为 1.0 或不写都会降级转发,握手必然失败
- proxy_set_header Upgrade $http_upgrade:用变量透传客户端原始值(如 websocket、mqtt 等),不能写死为 "websocket",否则非标准客户端升级会被截断
- proxy_set_header Connection "upgrade":必须是固定字符串 "upgrade",不是变量 $connection_upgrade;后者为空时 Nginx 会发 Connection: close,直接中断连接
关闭缓冲与延长超时时间
WebSocket 是长生命周期双向连接,Nginx 默认行为(缓冲响应、60 秒读超时)会破坏通信:
- proxy_buffering off:关闭响应缓冲,避免消息堆积、延迟或粘包,确保数据实时透传
- proxy_read_timeout 86400(24 小时):防止空闲连接被 Nginx 单方面关闭;设太小(如默认 60)会导致“无提示掉线”
- proxy_send_timeout 86400:保障服务端主动推送不因超时中断;该值作用于整个连接周期,不是单次发送
推荐的 location 配置结构
建议为 WebSocket 路径(如 /ws、/socket.io)单独定义 location,避免影响普通 HTTP 流量:
- 用 map 指令动态构造 Connection 值(更健壮):在 http 块中添加
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
然后在 location 中写 proxy_set_header Connection $connection_upgrade - 加上 tcp_nodelay on 降低传输延迟
- 保留 proxy_set_header Host $host,确保后端能正确识别原始域名
- 避免在该 location 中混用 rewrite 或其他可能干扰 Upgrade 头的指令
常见错误排查点
如果仍握手失败(返回 400、502 或卡在 pending),重点检查:
- 后端服务是否真正监听并响应 101 Switching Protocols —— Nginx 只负责转发,不处理升级逻辑
- 浏览器开发者工具 Network 标签页中,WebSocket 请求的 Request Headers 是否含 Upgrade: websocket 和 Connection: Upgrade
- Nginx 日志中是否有 upstream prematurely closed connection,通常指向 proxy_read_timeout 过短或后端未维持连接
- 确认没有在 server 或 http 块中全局覆盖了 proxy_set_header,导致 location 内配置被忽略


















