深浅主题
WebSocket 握手失败
问题现象
页面能打开,但实时连接失败;握手返回 200、301、400 或 403,没有 101 Switching Protocols。
适用环境
浏览器 WebSocket、HTTPS 反向代理、具备 WebSocket 端点的服务。
本文是可复用的排障示例,不代表某次个人生产事故。命令中的名称、账号和数据均为示例,执行前请替换为已确认的目标。
复现或诊断步骤
- 在浏览器 Network 的 WS 项检查 URL、Origin、状态和响应头,勿把带令牌 URL 复制到公开日志。
- 比较代理转发路径与后端端点,确认是否多加或剥离前缀。
- 在同一网络内测试后端,并检查认证、Origin 允许列表、Upgrade 支持和空闲超时。
原因分析
HTTPS 页面连接 ws:// 会触发混合内容限制。路由前缀错误可能把握手交给普通 HTML 服务。Caddy reverse_proxy 原生支持 WebSocket;Nginx 常需显式传递 Upgrade 与 Connection。握手成功后立即关闭则应继续检查应用协议和授权。
修复示例
caddyfile
app.example.com {
@socket path /socket /socket/*
handle @socket {
reverse_proxy realtime:8080
}
handle {
reverse_proxy web:8080
}
}
# handle 保留原始 /socket 路径;不要无意换成 handle_path浏览器使用 wss://,保持后端约定的路径和认证方式。配置心跳与合理空闲超时;更新代理前保存旧配置,说明热加载可能使长连接需要重连。客户端重连应退避,并重新完成授权。
验证方法
确认浏览器握手 101,再验证实际消息收发、空闲后的心跳与断线重连。没有有效登录凭据时,只能验证路由与握手拒绝原因,不能宣称完整会话成功。
常见误区
仅凭首页 200 不代表 WebSocket 正常。不要盲目允许所有 Origin,也不要把 WebSocket 令牌放入截图或工单;HTTP/2 扩展连接机制与 HTTP/1.1 握手需按链路区分。