必须同时配置proxy_http_version 1.1、proxy_set_header upgrade $http_upgrade、proxy_set_header connection "upgrade"及proxy_read_timeout/proxy_send_timeout(如3600),否则后端收不到升级信号,websocket握手失败或连接中断。

要在 Nginx 中正确支持 WebSocket 或其他需要协议升级(HTTP Upgrade)的场景,不能只配 proxy_set_header Upgrade,必须配合 Connection 头、HTTP 版本和超时等设置,否则后端收不到升级信号,连接会失败或断开。
Upgrade 头必须用 $http_upgrade 变量
客户端发起 WebSocket 连接时,请求头中自带 Upgrade: websocket。Nginx 默认不透传这个逐跳头(hop-by-hop),需显式转发:
- ✅ 正确写法:
proxy_set_header Upgrade $http_upgrade;
——$http_upgrade是 Nginx 内置变量,自动提取原始请求中的 Upgrade 值(如websocket),大小写和空格兼容性好 - ❌ 错误写法:
proxy_set_header Upgrade websocket;
——硬编码丢失灵活性,非 WebSocket 请求也可能触发该 location,导致后端误判 - ⚠️ 注意:
$http_upgrade在普通 HTTP 请求中为空,所以该配置对常规流量无副作用
Connection 头必须强制设为 "upgrade"
仅传 Upgrade 不够。WebSocket 升级要求服务端同时收到 Upgrade: websocket 和 Connection: upgrade —— 后者必须是精确字符串 upgrade,不能是 keep-alive, upgrade 或其他组合值:
FastAPI + Flask 混合部署最佳实践,解决路由定义、API 代理等常见问题,适用于同时运行 FastAPI API 与 Flask 前端的场景。
- ✅ 正确写法:
proxy_set_header Connection "upgrade";
——强制覆盖,语义明确,符合 RFC 和主流后端(Node.js、Spring Boot、Tomcat)识别逻辑 - ❌ 错误写法:
proxy_set_header Connection $http_connection;
——客户端可能发keep-alive,后端直接忽略升级意图
配套设置缺一不可
光设两个头只是起点。WebSocket 是长连接,还需调整协议版本与超时机制:
-
proxy_http_version 1.1;—— HTTP/1.0 不支持 Upgrade 机制,必须启用 1.1 -
proxy_read_timeout 3600;和proxy_send_timeout 3600;—— 防止空闲连接被 Nginx 主动关闭(默认 60 秒) -
proxy_cache_bypass $http_upgrade;—— 避免把 Upgrade 请求缓存,否则后续连接可能返回旧响应 -
proxy_set_header Host $host;—— 确保后端能正确解析 Host,尤其涉及多租户或动态路由时
典型 location 配置示例
把上述要点整合进实际配置块中:
location /ws {
proxy_pass http://backend_ws;
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_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
proxy_cache_bypass $http_upgrade;
}
配置完成后 reload Nginx,用浏览器开发者工具检查 WebSocket 握手请求:请求头应含 Upgrade: websocket 和 Connection: upgrade,响应状态码为 101 Switching Protocols。










