nginx代理websocket需显式配置协议升级头:proxy_http_version 1.1、proxy_set_header upgrade $http_upgrade、proxy_set_header connection "upgrade"、proxy_set_header host $host,并设置proxy_read_timeout和proxy_send_timeout为86400,关闭proxy_buffering。

直接上核心配置,Nginx 要让 Node.js 的 WebSocket(比如 Socket.io)稳定工作,关键不是“加个 proxy_pass 就完事”,而是必须显式处理协议升级头。否则浏览器发了 Upgrade: websocket 请求,Nginx 默认不透传,连接在握手阶段就断了。
WebSocket 反向代理必须配齐的 4 个头
Nginx 的 location 块里,这几行缺一不可:
- proxy_http_version 1.1:WebSocket 握手依赖 HTTP/1.1,旧版本默认用 1.0,会失败
-
proxy_set_header Upgrade $http_upgrade:把客户端带的
Upgrade: websocket原样转发给 Node 后端 - proxy_set_header Connection "upgrade":告诉 Nginx 这不是普通 HTTP 请求,要保持长连接并升级协议
- proxy_set_header Host $host:确保后端能正确识别请求来源,尤其影响 Socket.io 的 origin 校验逻辑
location 路径要匹配前端实际连接地址
比如你在 Vue 前端代码里写的是:
const socket = io('https://api.example.com/ws');那 Nginx 配置里 location 就得对上 /ws/ 或 /ws(注意末尾斜杠是否一致):
location /ws/ {
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;
}
如果后端 Node.js 服务监听在 http://localhost:3000,且 Socket.io 没改默认 path(即 /socket.io/),那更稳妥的写法是:
location /socket.io/ {
proxy_pass http://127.0.0.1:3000/socket.io/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
别漏掉超时和长连接设置
WebSocket 是长连接,Nginx 默认 60 秒就断连,必须延长:
- proxy_read_timeout 86400:读超时设为 24 小时,避免空闲断连
- proxy_send_timeout 86400:同理,写超时也拉长
- proxy_buffering off:关闭缓冲,防止消息被缓存延迟推送
HTTPS 下还要注意 wss 协议兼容性
前端用 wss:// 连接时,Nginx 必须启用 SSL,并确保后端 Node 服务本身支持 HTTPS 或由 Nginx 终止 SSL:
- server 块 listen 443 ssl,配好证书
- proxy_pass 地址用
http://(Nginx 解密后转 HTTP 给 Node),不要写成 https:// - Socket.io 客户端初始化时要明确传
{ secure: true, transports: ['websocket'] },避免降级到轮询











