宝塔反向代理默认不支持websocket,必须手动添加upgrade和connection头、匹配路径、配置ssl证书及延长超时时间:proxy_set_header upgrade $http_upgrade; proxy_set_header connection "upgrade"; proxy_read_timeout 3600;。

宝塔反向代理默认不支持 WebSocket,必须手动加 header
宝塔的 Nginx 反向代理界面里勾选“启用反向代理”后,proxy_pass 会自动生成,但默认不带 WebSocket 必需的 Upgrade 和 Connection 头,导致浏览器报 WebSocket is closed before the connection is established 或反复触发 onclose。
解决方法不是改配置模板,而是直接在反向代理设置页底部的「配置文件」区域追加以下三行(注意缩进与位置):
proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host;
这三行必须放在 location / { ... } 块内、proxy_pass 语句之后。漏掉 Host 头可能导致后端鉴权失败;把 Connection 写成 "keep-alive" 或漏引号也会失效。
location 路径必须匹配 WebSocket 的实际请求路径
很多前端用 new WebSocket("wss://example.com/ws"),但反向代理规则写的是 location / { proxy_pass http://127.0.0.1:8080; }——这会导致 WebSocket 请求被转发到后端根路径,而实际后端服务可能只监听 /ws 路由。
正确做法是显式声明 location 路径,并保持前后端路径一致:
- 前端连接地址用
wss://example.com/ws - 宝塔反向代理中添加一条规则:目标 URL 填
http://127.0.0.1:8080/ws(注意末尾/ws) - 或手动编辑配置,在
location /ws { ... }块里写proxy_pass http://127.0.0.1:8080/ws;(结尾斜杠必须一致)
路径不一致时,Nginx 默认会做路径重写,把 /ws 剪掉再拼到 proxy_pass 后,极易造成 404 或协议降级。
SSL 证书必须由宝塔托管,且 WSS 要求 SNI 正确
如果用自签名证书或外部 Nginx 终止 SSL,宝塔的反向代理无法透传 TLS 握手,wss:// 会直接失败,浏览器控制台显示 net::ERR_SSL_PROTOCOL_ERROR。
确保:
- 域名已添加到宝塔网站,SSL 选项中选择“Let's Encrypt”并成功签发
- 反向代理规则绑定的网站已启用 HTTPS(即“强制 HTTPS”开关打开)
- 后端服务本身不要重复处理 HTTPS——它只需响应 HTTP 的 WebSocket 升级请求
宝塔生成的 Nginx 配置中,HTTPS server 块会自动包含 ssl_protocols TLSv1.2 TLSv1.3;,无需手动改;但若手动删过 ssl 配置片段,WSS 握手会因协议不匹配中断。
超时时间不调长,连接 60 秒后必然断开
Nginx 默认 proxy_read_timeout 是 60 秒,WebSocket 空闲时无数据帧,就会被主动关闭,表现为前端突然触发 onclose 且 event.code === 1006。
在反向代理的配置文件中,location 块内必须显式设置:
proxy_read_timeout 3600; proxy_send_timeout 3600;
这两个值建议设为相同,且不低于你业务最长空闲容忍时间。设太高(如 86400)虽不报错,但会积压大量空闲连接,影响服务器并发能力。生产环境常见设为 3600~7200。
注意:这个 timeout 是从最后一次收/发数据开始计时,不是连接建立时间。心跳包不能替代它——即使前端每 30 秒发一次 ping,只要 Nginx 没收到,依然会超时。











