原生 websocket 浏览器直用但易出错,关键在协议必须为 ws:// 或 wss://、onmessage 需手动 json.parse、send 前须检查 readystate === websocket.open、onerror 与 onclose 要分离处理,并实现带退避的重连机制。

原生 WebSocket 不用装包、不用引入库,浏览器直接能用,但写错一行就收不到消息——关键在连接时机、数据格式和错误兜底。
WebSocket 构造函数必须用 ws:// 或 wss:// 协议
浏览器会直接拒绝 http:// 或 localhost:8080/ws 这类不带协议前缀的地址,报错 SecurityError: Invalid URL。
- 正确写法:
new WebSocket("ws://localhost:8080/ws")(开发)或new WebSocket("wss://api.example.com/ws")(生产) - 子协议可选,但后端没配好时传了反而连不上:
new WebSocket("ws://localhost:8080/ws", "chat") - 跨域不是问题:WebSocket 本身不走 CORS 检查,但服务端
setAllowedOrigins("*")配置必须存在(Spring Boot 场景)
onmessage 里必须手动 JSON.parse(e.data)
后端发来的几乎全是 JSON 字符串,e.data 是原始字符串,直接当对象用会报 TypeError: Cannot read property 'xxx' of undefined。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 安全写法:
const res = JSON.parse(e.data),且建议加 try-catch - 二进制数据(如 ArrayBuffer)需提前设置
ws.binaryType = "arraybuffer",否则e.data仍是 Blob - 别在
onopen里立刻 send 大量消息:连接刚建立时网络可能未稳,建议延迟 100ms 再发
onclose 和 onerror 必须分开处理
onclose 是正常断开(比如服务重启、用户关页),onerror 是连接失败或传输异常——两者触发条件不同,混着写容易漏重连逻辑。
-
onclose触发时,e.code是关闭码(如 1006 表示异常关闭,1001 表示服务端主动关闭) -
onerror不传具体错误对象,只抛事件,err.message常为空,得靠日志或状态码判断 - 重连不能无脑
setTimeout(() => new WebSocket(...), 1000):要防抖(lockReconnect)、限频(最大重试 5 次)、退避(每次延时翻倍)
send 前必须检查 readyState === WebSocket.OPEN
页面切后台、网络抖动、连接正在重连时,ws.readyState 可能是 0(CONNECTING)或 2(CLOSING)或 0(CLOSED),此时调 send 会静默失败,控制台也不报错。
- 发送前务必加判断:
if (ws && ws.readyState === WebSocket.OPEN) { ws.send(...) } - 消息堆积时别直接丢弃:可缓存队列,在
onopen后批量 flush - 心跳包要用
ping/pong帧?别折腾——原生 API 不暴露 ping/pong 控制权,用send(JSON.stringify({ type: "ping" }))最实在
真正难的不是写通第一行 new WebSocket,而是让连接在弱网、切后台、服务重启后还能自动续上,并且消息不丢、不重复、不乱序。这些细节藏在 onclose 的 code 判断里、藏在重连定时器的退避策略里、也藏在每次 send 前那行看似多余的 readyState 检查里。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










