
DexTools 的 WebSocket 服务(wss://ws.dextools.io)返回 403 错误,主因是缺失 Cloudflare 防护所需的 __cf_bm 等关键 Cookie,而非请求头或协议问题;浏览器能连通是因为自动携带了已获取的有效防护 Cookie,而 Node.js 客户端需手动模拟完整会话流程。
dextools 的 websocket 服务(wss://ws.dextools.io)返回 403 错误,主因是缺失 cloudflare 防护所需的 __cf_bm 等关键 cookie,而非请求头或协议问题;浏览器能连通是因为自动携带了已获取的有效防护 cookie,而 node.js 客户端需手动模拟完整会话流程。
Cloudflare 的 Bot Management(CF-BM)机制会为合法浏览器会话颁发短期有效的加密 Cookie(如 __cf_bm),并在后续 WebSocket 握手时强制校验。你当前的 Node.js 代码仅复制了浏览器的请求头,但未复现「先访问主页触发 CF 挑战 → 获取有效 Cookie → 携带 Cookie 发起 WS 连接」这一关键链路,因此服务端直接拒绝连接。
✅ 正确做法是分两步实现:
- 先向主页发起 HTTP GET 请求,提取并保存 Cloudflare 设置的 Cookie;
-
在 WebSocket 连接中通过
headers.Cookie显式传递该 Cookie。
以下为可运行的完整示例(使用 node-fetch + ws):
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
npm install node-fetch ws tough-cookie
import fetch from 'node-fetch';
import { WebSocket } from 'ws';
import { CookieJar } from 'tough-cookie';
const cookieJar = new CookieJar();
// Step 1: 访问主页,触发 Cloudflare 并获取 __cf_bm 等 Cookie
await fetch('https://www.dextools.io', {
method: 'GET',
headers: {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
},
credentials: 'include',
// 注意:node-fetch v3+ 需配合 tough-cookie 手动管理 Cookie
}).then(res => {
// 自动解析 Set-Cookie 并存入 jar(需适配 fetch 配置)
return res.text();
});
// ⚠️ 实际项目中建议用 axios 或封装 fetch + cookieJar(见下方说明)
// 此处为简化演示,假设已获取到有效 Cookie 字符串:
const cookies = '__cf_bm=jiZr1.iD14zSdlq3TDmxUQvZTxH2JTOsuKr9STDjnq8-1705066768-1-Ac4Klcp8MicpEYiED2SRMIZD8esaChu3QnUpz06Ko0tihhUGrWQ2W+nTzwRz9Jlyc/SEXl31IxjDVXshcexX+dw=; path=/; domain=.dextools.io; Secure; HttpOnly; SameSite=None';
// Step 2: 使用携带 Cookie 的 WebSocket 连接
const ws = new WebSocket('wss://ws.dextools.io', {
headers: {
'Cookie': cookies,
'Origin': 'https://www.dextools.io',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
'Sec-WebSocket-Version': '13',
}
});
ws.on('open', () => console.log('✅ WebSocket connected successfully'));
ws.on('error', err => console.error('❌ WebSocket error:', err.message));
ws.on('message', data => console.log('? Received:', data.toString()));
? 关键注意事项:
-
__cf_bmCookie 有效期通常仅 30 分钟左右,需定期刷新(建议在连接前重新抓取); - 不要硬编码 Cookie —— 应构建自动化流程:HTTP GET 主页 → 解析响应头中的
Set-Cookie→ 提取__cf_bm→ 注入 WS 请求; -
Origin必须设为https://www.dextools.io(而非chrome://newtab),否则部分防护策略可能拦截; - 若遇到 Cloudflare “Under Attack” 页面(HTTP 503 / HTML 响应),说明挑战未通过,需引入 Puppeteer 模拟真实浏览器完成 JS 挑战(进阶场景);
-
ws库不支持自动 Cookie 管理,务必手动注入Cookie请求头。
? 总结:WebSocket 403 不是协议错误,而是反爬防护的明确信号。解决核心在于复现浏览器的完整会话上下文——尤其 Cookie 生命周期与来源一致性。跳过首页预热、依赖静态头信息或忽略域级 Cookie 策略,均会导致握手失败。










