必须手动添加proxy_set_header Upgrade $http_upgrade和Connection "upgrade",因宝塔“启用代理Websocket”仅标记不生成关键头;Nginx默认丢弃Upgrade/Connection头,致握手失败返回400而非101,后端无日志。

必须手动编辑 Nginx 配置文件补全 proxy_set_header Upgrade $http_upgrade 和 proxy_set_header Connection "upgrade",宝塔 UI 的「启用代理Websocket」开关仅做标记,不自动生成关键头字段。
为什么勾选「启用代理Websocket」后 WSS 仍连接失败
宝塔面板的「启用代理Websocket」只是在配置中打个标记,并不会自动注入 WebSocket 升级必需的两个请求头。Nginx 默认把 Upgrade 和 Connection 当作非标准头丢弃,导致浏览器发起 ws:// 或 wss:// 握手时,后端收不到 Upgrade: websocket,直接返回 200/400 而非 101 Switching Protocols。
常见现象包括:
- 浏览器控制台显示
Error during WebSocket handshake: Unexpected response code: 400 - 后端日志完全无握手请求记录(说明请求甚至没抵达服务)
- 使用
curl -i -H "Upgrade: websocket" -H "Connection: upgrade" http://your-domain.com测试,响应里没有101状态码
在哪加、怎么加这两行头
必须进到站点对应的 Nginx 配置文件,在 location / { ... } 块内、proxy_pass 指令正下方添加,顺序不能错,缩进需对齐:
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
注意:
-
proxy_http_version 1.1必须开启,HTTP/1.0 不支持协议升级 -
$http_upgrade是 Nginx 内置变量,大小写敏感,不能写成$HTTP_UPGRADE -
Connection "upgrade"的引号不能漏,值必须是小写upgrade,不是Upgrade - 如果用了路径前缀(如
/api/),location块要对应写成location /api/ { ... },且proxy_pass末尾不能多加斜杠
HTTPS 场景下还要处理 SSL 证书校验
当目标地址是 https://127.0.0.1:8443 这类 HTTPS 后端时,Nginx 默认会校验其证书。若后端用的是自签名证书或域名不匹配,就会卡在 TLS 握手阶段,表现为 502 或超时,而不是 WebSocket 握手失败。
此时需在同个 location 块里加:
proxy_ssl_verify off; proxy_ssl_trusted_certificate /dev/null;
或者更稳妥的做法是:在 proxy_pass 上方加 proxy_ssl_server_name on; 并确保后端证书的 CN 或 SAN 匹配你填的目标域名。
Apache 用户别走 Nginx 路子
如果你用的是 Apache(宝塔可切换 Web 服务器),proxy_set_header 这套语法完全无效。Apache 需用 ProxyRequests Off + ProxyPass / ws://127.0.0.1:3000/,并显式启用 mod_proxy_wstunnel 模块。配置路径是 /www/server/panel/vhost/apache/你的域名.conf,且必须确认模块已加载——这点比 Nginx 容易被忽略。


















