websocket事件需按语义正确处理:onopen在连接真正就绪(readystate=1)时触发,初始化发送逻辑应放其中;onmessage需根据data类型(blob/arraybuffer/string)分别处理;onerror表示异常发生而非连接终止,不应调用close;onclose才标志连接结束,需依据code/reason判断原因并重连。

onopen 事件:连接建立后立即触发,但 readyState 可能还没稳定
创建 WebSocket 实例后,onopen 并非「构造完成就执行」,而是在 TCP 握手完成、HTTP 升级响应成功、且底层通道真正可用时才触发。此时 readyState 一定是 1(OPEN),但要注意:不能在 onopen 外部立刻调用 send(),因为 JS 执行顺序可能快于事件调度队列。
- 推荐做法:所有初始化发送逻辑(如认证包、订阅指令)统一放在
onopen回调内 - 常见错误:在
new WebSocket(url)后直接ws.send(...),此时readyState很可能是0(CONNECTING),导致InvalidStateError - 调试技巧:在
onopen中打印ws.readyState和Date.now(),确认是否真正在连接就绪后执行
onmessage 事件:data 类型不固定,必须主动判断
onmessage 的 evt.data 可能是 string、Blob 或 ArrayBuffer,取决于服务端发送方式和浏览器实现。默认情况下,文本消息为 string,二进制消息则按 binaryType 设置决定(默认 "blob")。
- 若服务端发的是 JSON 字符串,直接
JSON.parse(evt.data)即可;但若服务端发的是 ArrayBuffer,需先转成字符串再解析,否则报错 - 避免写死
typeof evt.data === "string"判断——某些浏览器在binaryType = "arraybuffer"下仍可能把小消息当作 string 返回 - 稳妥做法:先检查
evt.data instanceof Blob或evt.data instanceof ArrayBuffer,再做相应处理 - 示例:
ws.onmessage = function(evt) { let data; if (evt.data instanceof Blob) { data = await evt.data.text(); } else if (evt.data instanceof ArrayBuffer) { data = new TextDecoder().decode(evt.data); } else { data = evt.data; } console.log(JSON.parse(data)); };
onerror 事件:不表示连接已断,而是「异常发生中」
onerror 是一个信号事件,不是终态通知。它通常在底层网络失败、证书校验失败、协议升级被拒绝等场景下触发,但此时连接未必已关闭——readyState 仍可能是 0 或 1,且后续大概率会紧跟着触发 onclose。
- 不要在
onerror里调用ws.close(),这属于重复操作,还可能引发InvalidStateError - 真正该做的事:记录错误上下文(如
evt.target.url、ws.readyState)、触发重连逻辑(但需加防抖,避免雪崩)、清除未决的setTimeout定时器(比如心跳超时检测) - 注意:Chrome 有时会在 CORS 失败时只触发
onerror而不触发onclose,需单独处理
onclose 事件:code 和 reason 才是关键诊断信息
onclose 的 evt.code 和 evt.reason 比单纯「连接断了」有用得多。它们由服务端或浏览器主动设置,例如服务端调用 close(4001, "auth failed"),客户端就能拿到对应值。
-
evt.code === 1000表示正常关闭;1006是异常关闭(无明确原因,常因网络中断);4000–4999是自定义业务码,需和服务端对齐 -
evt.reason在大多数现代浏览器中可用,但 Safari 旧版本可能为空字符串,别依赖它做关键逻辑分支 - 容易忽略的一点:即使
onclose触发,ws实例对象依然存在,ws.readyState已变为3(CLOSED),再次send()会静默失败——必须新建实例才能重连
onerror 和 onclose 的时间差与语义差异:前者是「出事了」,后者才是「结束了」。实际项目里,把重连逻辑只挂在 onclose 上,会漏掉大量 onerror 后未触发 onclose 的半死连接。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











