原生 WebSocket 必须用 ws:// 或 wss:// 协议,否则报错;onmessage 中 event.data 类型需判断再处理;send 前须校验 readyState === WebSocket.OPEN;onerror 无具体错误信息,应依赖 onclose.code 判断断连原因并重建实例。

原生 JS 调用 WebSocket 不需要第三方库,但必须处理好连接状态、重连、序列化和错误边界——否则页面看似连上了,实际发不出消息或收不到回调。
创建 WebSocket 实例时 URL 必须带协议头
直接写 'localhost:8080' 或 '/ws' 会报 SecurityError 或 SyntaxError。浏览器强制要求协议标识符:ws://(非加密)或 wss://(加密,生产环境必须用)。
-
new WebSocket('ws://localhost:8080')✅ -
new WebSocket('wss://api.example.com/chat')✅ -
new WebSocket('localhost:8080')❌ 报错:Failed to construct 'WebSocket': The URL's scheme must be either 'ws' or 'wss' -
new WebSocket('/ws')❌ 协议缺失,解析失败
onmessage 回调里 event.data 类型不固定
服务端发来什么,event.data 就是什么类型:可能是字符串、Blob、ArrayBuffer。前端不判断就直接 JSON.parse() 会炸。
- 如果后端明确只发 JSON 字符串,可加 guard:
if (typeof event.data === 'string') { JSON.parse(event.data) } - 如果后端可能发二进制(如图片帧、protobuf),需提前约定并检查:
event.data instanceof Blob或event.data instanceof ArrayBuffer - 不要依赖
ws.binaryType = 'arraybuffer'后就忽略类型判断——它只影响后续接收,不改变已发数据的原始类型
send() 前必须确保 readyState === WebSocket.OPEN
WebSocket.OPEN 是唯一安全发送的状态。在 onopen 外调用 send(),大概率触发 InvalidStateError,尤其在快速重连或网络抖动时。
立即学习“前端免费学习笔记(深入)”;
- 正确做法是封装发送逻辑:
function safeSend(data) { if (ws.readyState === WebSocket.OPEN) { ws.send(data); } else if (ws.readyState === WebSocket.CONNECTING) { // 可缓存,等 open 后再发;或丢弃 + 提示 } } - 别在
onopen里直接发一堆消息——服务端可能还没准备好,建议加微小延迟或等服务端确认就绪后再批量发 -
ws.bufferedAmount> 0 说明有积压,但不等于失败;它只是提示“还没真正发出去”,不是错误信号
error 和 close 事件不能只 console.log
这两个事件是连接异常的唯一体现入口。onerror 不传具体错误对象(Chrome/Firefox 都只给空 event),onclose 的 event.code 才是关键线索。
-
event.code === 1006:异常断连(没发 close 帧,典型网络中断)→ 应触发重连 -
event.code === 1000:正常关闭 → 不重连 -
event.code >= 4000:自定义业务错误码(如鉴权失败 4001)→ 清理状态,跳登录页 -
onerror里不要只写console.error(error),它几乎总是undefined;重点看onclose和网络面板里的 WebSocket 帧
最常被忽略的是:WebSocket 连接一旦关闭,ws 实例就不可复用。哪怕你没手动 ws.close(),断连后也必须 new WebSocket(...) 新建实例——重用旧对象只会让 readyState 卡在 CLOSED,且所有事件监听器失效。



















