new WebSocket() 必须传带 ws:// 或 wss:// 协议的绝对 URL,如 "ws://localhost:8080" 或 "wss://api.example.com/ws";省略协议、用相对路径或 http:// 均会抛 DOMException 错误。

直接用 new WebSocket() 就能连上,但连不上、收不到消息、发不出数据——90% 的问题出在没等 readyState === WebSocket.OPEN 就调 send(),或者没处理 onerror 和重连逻辑。
WebSocket 构造函数怎么传参才不报错
URL 必须带协议前缀,且不能是相对路径;常见错误是写成 "localhost:8080" 或 "/ws",这会触发 DOMException: Failed to construct 'WebSocket'。
-
"ws://localhost:8080"用于本地开发(非 HTTPS 页面) -
"wss://api.example.com/ws"用于生产环境(HTTPS 页面必须用wss://,否则浏览器直接拒绝) - 第二个参数
protocols是可选字符串或字符串数组,比如["json", "binary"],服务端需匹配才接受连接;不填就留空或省略
为什么 ws.send() 突然没反应
最常踩的坑:在 onopen 外调 send(),或在 readyState 不为 1 时强行发。WebSocket 不是“创建即可用”,它有明确状态机。
- 检查
ws.readyState:只有WebSocket.OPEN(即值为1)才能安全调send() - 不要在
onopen回调外直接写ws.send("xxx"),哪怕只差一行代码,也可能执行在CONNECTING阶段 - 如果发的是二进制数据(
Blob或ArrayBuffer),确保服务端支持该类型;纯字符串最稳
onmessage 收不到服务端推送怎么办
不是服务端没推,而是前端没正确监听或解析。WebSocket 传的是原始消息体,event.data 可能是字符串、Blob 或 ArrayBuffer,取决于服务端发什么。
立即学习“前端免费学习笔记(深入)”;
- 默认情况下,服务端发 JSON 字符串,前端要手动
JSON.parse(event.data) - 如果服务端发的是
ArrayBuffer,event.data就是二进制,不能直接.toString(),得用TextDecoder或Uint8Array处理 - 别漏掉
onerror:例如服务端关闭连接时返回非标准状态码,可能触发onerror而非onclose,不监听就静默失败
如何安全关闭并避免重复连接
ws.close() 是主动断开,但调用后状态不会立刻变 CLOSED;更麻烦的是,页面刷新或意外断开后,没人管这个对象,容易堆积无效连接。
- 调
ws.close(1000, "normal close")时,建议加 code 和 reason,方便服务端日志归因 - 关闭前检查
ws.readyState:只在OPEN(1)或CLOSING(2)时调close(),否则会抛错 - 避免自动重连写成死循环:检测到
onclose后,用setTimeout延迟几秒再 new,且限制最大重试次数(比如 5 次),不然网络抖动时会狂建连接
真正难的不是写通第一行 new WebSocket(),而是把 readyState 状态流转、错误边界、二进制/文本混合收发、以及页面生命周期(如切标签页、刷新)下的连接管理全兜住——这些细节不处理,上线后就是偶发性收不到消息、内存泄漏、或大量 WebSocket is already in CLOSING or CLOSED state 报错。



















