Dashboard 卡在 Loading Chat?—— WebSocket 连接错误地址排查实录

OpenClaw WebSocket Dashboard 浏览器缓存

问题描述

某天打开 OpenClaw Dashboard,页面加载后一直卡在 "Loading chat...",浏览器控制台显示:

WebSocket connection to 'ws://100.x.y.z:18789/ws?token=...' failed:
Error during WebSocket handshake: Unexpected response code: 403

关键问题:明明访问的是 http://127.0.0.1:18789,WebSocket 却尝试连接 ws://100.x.y.z:18789(Tailscale IP)!

排查过程

第一阶段:服务端检查

检查项 状态 详情
Gateway 服务 ✅ 正常 PID 12238 运行中
端口监听 ✅ 正常 127.0.0.1:18789
HTTP 服务 ✅ 正常 返回 200 OK
Node.js 版本 ✅ 正常 v24.3.0 (≥22)
防火墙 ✅ 已关闭 State = 0
认证 Token ✅ 正常 mode: token
QClaw 冲突 ✅ 无冲突 QClaw 用 28789 端口

服务端一切正常,问题不在 Gateway。

第二阶段:前端分析

检查前端 JavaScript 如何构建 WebSocket URL:

// 前端代码逻辑
const wsUrl = `${location.protocol === "https:" ? "wss" : "ws"}://${location.host}/ws`;

代码本身没问题,location.host 应该返回当前页面的 host。但浏览器实际连接的却是:

实际访问: http://127.0.0.1:18789/
WebSocket 尝试: ws://100.x.y.z:18789/  ← 错误!
100.x.x.x 是 Tailscale 的 IP 地址范围!这说明浏览器或其缓存"记住"了一个 Tailscale 地址。

第三阶段:环境检查

检查项 结果
Tailscale 进程 ❌ 未运行
Tailscale LaunchDaemon 不存在
OpenClaw Tailscale 配置 mode: "off"
QClaw Tailscale 配置 mode: "off"

Tailscale 完全关闭,但 WebSocket 仍尝试连接 Tailscale IP!

根本原因

用户访问: http://127.0.0.1:18789/ ↓ 浏览器检查: "这个站点我之前访问过吗?" ↓ 找到历史: "是的,之前是 http://100.x.y.z:18789/" ↓ Service Worker: "我有缓存的 JS 文件" ↓ 缓存中的 JS: location.host = "100.x.y.z" ↓ WebSocket 连接: ws://100.x.y.z:18789/ ← 错误!

核心问题:浏览器缓存(包括 Service Worker)保存了之前通过 Tailscale IP 访问时的资源,导致 location.host 被污染。

解决方案

方案 1:清除 Service Worker(推荐)

  1. Chrome 地址栏输入 chrome://serviceworker-internals/
  2. 搜索 127.0.0.1
  3. 点击 Unregister 注销所有 Service Worker
  4. 关闭所有 127.0.0.1:18789 标签页
  5. 重新打开 http://127.0.0.1:18789/

方案 2:无痕模式测试

  1. Cmd + Shift + N 打开无痕窗口
  2. 访问 http://127.0.0.1:18789/
  3. 如果无痕模式正常,确认是缓存问题

方案 3:禁用浏览器扩展

  1. Chrome 地址栏输入 chrome://extensions/
  2. 关闭所有扩展(特别是 Tailscale 相关)
  3. 刷新 Dashboard

方案 4:完全清除站点数据

  1. Chrome 地址栏输入 chrome://settings/siteData
  2. 搜索 127.0.0.1
  3. 点击删除
  4. 清除浏览器历史中的 100.x.x.x:18789 记录

预防措施

1. 统一访问方式

始终使用 127.0.0.1localhost 访问本地 Dashboard,避免混用 Tailscale IP。

2. 定期清理

# macOS 清理 Service Worker 缓存
rm -rf ~/Library/Application\ Support/Google/Chrome/Default/Service\ Worker/Cache*
rm -rf ~/Library/Application\ Support/Google/Chrome/Default/Cache/*

3. 使用带 Token 的完整 URL

# 每次使用最新 Token
openclaw dashboard --no-open

# 复制完整 URL(包含 #token=xxx)
# 在无痕窗口打开

排查流程总结

问题出现

Dashboard 卡在 Loading chat,WebSocket 连接失败

检查服务端

Gateway、端口、认证、防火墙 - 全部正常

检查前端

发现 WebSocket 连接的是错误的 Tailscale IP

检查环境

Tailscale 未运行,但浏览器缓存了旧地址

定位根因

浏览器 Service Worker 缓存污染了 location.host

解决问题

清除 Service Worker,重新生成 Token,重启 Gateway

诊断命令速查

# 检查 Gateway 状态
openclaw gateway status

# 检查端口监听
lsof -i :18789

# 检查健康状态
curl http://127.0.0.1:18789/health

# 检查 Tailscale 状态
tailscale status

# 生成新的 Dashboard URL
openclaw dashboard --no-open

# 重启 Gateway
openclaw gateway restart

✅ 问题已解决

根本原因:浏览器缓存/Service Worker 缓存了之前通过 Tailscale IP 访问时的前端资源,导致 WebSocket 尝试连接错误的地址。

解决方案:清除 Service Worker 缓存或使用无痕模式访问。

预防措施:统一使用 127.0.0.1 访问本地 Dashboard,避免混用 Tailscale IP。

📖 更多文章

1/4