nginx代理websocket需正确透传upgrade和connection头:设proxy_set_header upgrade $http_upgrade;与proxy_set_header connection "upgrade";,并配置proxy_http_version 1.1;于location块内。

要让 Nginx 正确代理 WebSocket,关键就是把客户端发起的协议升级请求完整、准确地透传给后端服务。Upgrade 和 Connection 这两个头是 WebSocket 握手成功的硬性前提,缺一不可,且写法有明确规范。
必须显式设置 Upgrade 头
客户端在发起 WebSocket 连接时,会带上 Upgrade: websocket 请求头。Nginx 默认不转发这个头,必须手动配置:
-
正确写法:
proxy_set_header Upgrade $http_upgrade; - 使用
$http_upgrade变量能原样保留客户端原始值(比如websocket、h2c或空),兼容多种升级场景 - 不能写成
proxy_set_header Upgrade websocket;—— 硬编码会破坏非标准协议(如 STOMP)或客户端未带 Upgrade 头时的行为
Connection 头必须设为固定字符串 "upgrade"
这个头不是简单透传,而是告诉 Nginx:“请执行协议切换”,所以它必须是明确指令:
-
最稳妥写法:
proxy_set_header Connection "upgrade"; - 不要用
$http_connection—— 它常含多个值(如"Upgrade, keep-alive"),Nginx 清理后只剩keep-alive,后端收不到升级信号 - 如果已定义
map $http_upgrade $connection_upgrade { default upgrade; '' close; },也可写proxy_set_header Connection $connection_upgrade;,更严谨处理空 Upgrade 场景
配套基础配置不能少
只设这两个头还不够,它们依赖 HTTP/1.1 协议机制才能生效:
-
强制启用 HTTP/1.1:
proxy_http_version 1.1;—— HTTP/1.0 不支持 Upgrade,没这句握手直接失败 - 这两行必须放在具体的
location块内,不能只写在server或http块顶层 - 路径需精准匹配(例如
location /ws/ { ... }),避免被其他 location 拦截或覆盖
验证是否生效
配置生效后,用浏览器开发者工具检查 WebSocket 连接的请求和响应头:
- 请求中应出现:
Upgrade: websocket和Connection: upgrade - 响应状态码应为
101 Switching Protocols - 响应头也应包含相同的
Upgrade和Connection字段 - 若返回 400、502 或连接秒断,优先检查这两项头是否缺失、拼写错误或被其他规则覆盖











