WebSocket握手400错误主因是Nginx未透传Upgrade和Connection头及未设HTTP/1.1。需配置proxy_set_header Upgrade $http_upgrade、proxy_set_header Connection "upgrade"、proxy_http_version 1.1,并禁用缓存与重写。

WebSocket 握手阶段返回 400 错误,通常不是后端应用的问题,而是 Nginx 在代理过程中拒绝了升级请求。核心原因在于 Nginx 默认不支持或未正确配置 WebSocket 所需的 HTTP 协议升级(Upgrade: websocket 和 Connection: upgrade)头字段。
检查并透传关键升级头字段
Nginx 默认会过滤掉 Upgrade 和 Connection 这类“非标准”请求头,导致后端收不到握手信号,直接返回 400。必须显式配置透传:
- 在
location块中添加:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; -
$http_upgrade是 Nginx 内置变量,会自动捕获客户端发来的Upgrade头(值通常是websocket) -
Connection必须写成字面量"upgrade"(加引号),不能用变量,否则可能被忽略或转义
确认 proxy_http_version 版本为 1.1
WebSocket 升级依赖 HTTP/1.1 的连接管理机制。Nginx 默认使用 1.0,必须强制升级:
- 添加配置:
proxy_http_version 1.1; - 该指令必须放在
location或server块内,且对当前 WebSocket 路径生效 - 如果用了
proxy_pass指向 upstream,也要确保 upstream 块里没覆盖该设置
避免缓存或重写干扰握手请求
某些看似无关的配置会在握手阶段引发 400:
- 禁用缓存:
proxy_cache off;
proxy_buffering off;(缓冲可能截断分块传输) - 不要对 WebSocket 路径做
rewrite或return,尤其避免匹配/ws类路径时误加 trailing slash 重定向 - 检查是否启用了
underscores_in_headers on—— 若客户端头含下划线(如自定义X_WebSocket_Id),Nginx 默认丢弃整条请求,报 400
验证与快速定位技巧
光改配置不够,要确认实际请求是否达标:
- 用
curl模拟握手,观察 Nginx access log 是否记录 400,以及 error log 有无client sent invalid request等线索 - 开启 Nginx debug 日志(
error_log /path/to/error.log debug;),搜索upgrade、websocket、http header关键词 - 对比浏览器 DevTools Network 中的请求头和 Nginx access log 记录的原始头,确认
Upgrade和Connection是否到达 Nginx - 临时把
proxy_pass改成一个静态响应(如返回 200 + headers),确认 Nginx 层能正常接收并透传升级头


















