onopen 必须在 new websocket() 后立即绑定,触发即表示握手完成、readystate 为 1,可安全调用 send;onerror 不代表连接失败,判断依据仅为 onopen 是否执行。

直接给 ws.onopen 赋值一个函数,连接成功握手完成时就会触发——这是唯一、标准、无需额外库的方式。
onopen 必须在创建实例后立即绑定
WebSocket 是异步建立的,事件可能在你还没来得及监听前就发生了。所以不能等页面加载完或某个条件满足后再设 onopen。
- 正确写法:创建
new WebSocket(url)后立刻赋值ws.onopen = function() {...} - 错误写法:先声明
const ws = new WebSocket(...),隔几行再写ws.onopen = ...(有丢失事件风险) - 如果用 addEventListener,也必须紧随实例创建之后调用:
ws.addEventListener('open', handler)
onopen 触发即代表可安全通信
它只在 ws.readyState === WebSocket.OPEN(即数值为 1)时执行,说明协议握手已完成,TCP 连接已就绪。
- 此时可以放心调用
ws.send(),不会报错 - 不需要再检查
readyState—— onopen 本身已是状态确认信号 - 常见用途:发送登录凭证、订阅频道、上报客户端信息等初始化动作
别把 onerror 当作连接失败判断依据
onerror 不是“连接失败专用事件”,它可能在 DNS 错、SSL 拒绝、跨域拦截、甚至 send 失败时都触发,且不带具体错误信息。
- 真正判断连接是否成功,就看 onopen 是否执行
- 如果长时间没触发 onopen,再结合
ws.readyState判断:仍是 0(CONNECTING)说明卡在握手,是 3(CLOSED)说明已失败 - 不要在 onerror 里重连——可能误判;应在 onclose 或定时检测 readyState !== 1 后再决策
简单可靠的初始化示例
注意注释里的关键点:
const ws = new WebSocket('wss://api.example.com/ws');
// ✅ 立即绑定,不延迟
ws.onopen = function(event) {
console.log('✅ 连接成功,readyState =', this.readyState); // 一定是 1
this.send(JSON.stringify({ type: 'auth', token: 'xxx' }));
};
ws.onerror = function(event) {
// ⚠️ 仅用于记录,不用于判定连接结果
console.warn('⚠️ 发生异常(原因未知)', event);
};
ws.onclose = function(event) {
console.log('❌ 连接关闭,code=', event.code, 'clean=', event.wasClean);
};











