本地连 ws://127.0.0.1:8080/ws 一切正常,套上 nginx 后握手直接返回 426 Upgrade Required,access.log 里状态码 101 一条都没有。第一次遇到会往复杂处想,其实漏掉的多是个小前提。
location /ws {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
nginx 默认按普通 HTTP 请求转发,Connection 和 Upgrade 这两个逐跳头会被清掉,后端看到的是普通 GET,只能回 426。proxy_http_version 还是 1.0 时更彻底,升级根本没有通道。这一点先确认清楚,后面就不用反复试。
「Upgrade 头丢失」这个问题文档写得含糊,实际行为以当前版本为准,别照旧版本的结论套。把复现步骤压到三条以内,交给同事也能跑出来,才算真的定位清楚。
改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。
能分两步做的操作就别合成一步,中间看一眼返回值,出问题好判断。报错里带路径的,先去看那个路径在不在、权限对不对。
具体做法是,在 location 里显式写 proxy_set_header Upgrade 取 $http_upgrade;同时补 proxy_set_header Connection "upgrade" 这一行不能省;把 proxy_http_version 提到 1.1;重载配置后看 access.log 里有没有 101。
改完照着核一遍,响应状态码从 426 变成 101 switching protocols Network 面板里能看到 Upgrade 请求头。
