Nginx 不处理浏览器兼容性,仅透传原始 WebSocket 握手请求;需配置 proxy_set_header Upgrade $http_upgrade 和 Connection $connection_upgrade,禁用缓冲、压缩与缓存,并确保路径匹配严格一致。

Nginx 本身不处理浏览器版本兼容性,也不解析或降级 WebSocket 协议帧。所谓“旧版本浏览器适配”,实际是指:确保握手请求能被正确透传,让后端服务有机会根据客户端能力做兼容决策。Nginx 的角色只是可靠地把原始 Upgrade 请求送达,不破坏、不改写、不缓存。
必须保留原始 Upgrade 和 Connection 头
旧版浏览器(如 IE10、Android 4.3 WebView)可能发送非标准值(如 Upgrade: WebSocket 大写 W,或 Connection: upgrade 小写),Nginx 默认会过滤或标准化这些逐跳头。
需显式配置:
-
proxy_set_header Upgrade $http_upgrade;—— 原样转发客户端所带的 Upgrade 值 -
proxy_set_header Connection $connection_upgrade;—— 使用内置变量$connection_upgrade(Nginx ≥1.3.10),它在$http_upgrade非空时自动设为"upgrade",否则为"close"
⚠️ 切勿写死Connection "upgrade",否则普通 HTTP 请求会被误升级,引发 400 错误
不强制协议版本,但必须禁用 HTTP/2 干扰
旧浏览器基本不支持 HTTP/2,但若 Nginx 主 server 启用了 listen 443 ssl http2,ALPN 协商仍可能干扰握手流程(尤其在 TLS 终止场景)。
稳妥做法是:
- 为 WebSocket 流量单独配置子域名(如
ws.example.com),其 server 块中 不加http2参数 - 或使用路径隔离(如
/ws/),并在该 location 中确保proxy_http_version 1.1显式生效
关闭可能破坏握手的中间处理
旧浏览器对响应延迟、头字段顺序、缓冲行为更敏感:
-
proxy_buffering off;—— 防止 Nginx 缓存 Upgrade 响应,导致握手超时 -
proxy_cache_bypass $http_upgrade;—— 确保带 Upgrade 头的请求不走缓存 -
gzip off;—— WebSocket 帧不可压缩,开启 gzip 可能导致帧解析错乱 -
client_max_body_size 0;—— 避免 Nginx 尝试读取二进制帧体并触发 body 超限中断
路径匹配要严格一致,避免重写偏差
旧浏览器不会自动修正路径错误。例如前端连 ws://example.com/ws/chat,但 Nginx 配置为:
location /ws { proxy_pass http://backend; }会导致后端收到 /chat(/ws 被截断),而实际需要的是 /ws/chat。
正确写法:
-
location /ws/ { proxy_pass http://backend/ws/; }—— 末尾斜杠保持路径层级 - 或
location /ws { proxy_pass http://backend; }+rewrite ^/ws(.*)$ /ws$1 break;(慎用,优先选前一种)
Nginx 不参与协议协商,也不模拟旧版行为。它的兼容性保障,就是把原始请求原封不动、不加修饰地交到后端手里。


















