WebSocket需用new WebSocket("wss://...")显式指定协议,连接后须监听open事件再send;收消息用onmessage,二进制需设binaryType;断线重连需清旧实例、指数退避并区分关闭码。
直接用 new WebSocket() 就能发起连接,但必须传入有效的 wss:// 或 ws:// URL。浏览器不支持协议自动降级,ws:// 在 HTTPS 页面会被拒绝,必须用 wss://。
常见错误:传入相对路径(如 "/ws")或漏写协议,会报 SecurityError 或 SyntaxError: Invalid URL。
const ws = new WebSocket("wss://api.example.com/ws")
new WebSocket("localhost:8080") 会失败ws://localhost:8080,但上线必须切 wss
WebSocket 是事件驱动的,靠监听 open、message、error、close 四个核心事件工作。别在 new WebSocket() 后立刻调用 send() —— 连接还没就绪。
典型误操作:没等 open 就发数据,导致 InvalidStateError: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state。
ws.readyState === WebSocket.OPEN,推荐用 ws.onopen 回调保证时机ws.onmessage = (event) => { console.log(event.data) },event.data 默认是字符串,二进制需设 ws.binaryType = "arraybuffer"
send() 支持字符串、Blob、ArrayBuffer、TypedArray,但不能直接传对象,得先 JSON.stringify()
WebSocket 没内置重连机制,网络抖动、服务重启、NAT 超时都会触发 close 事件,此时 readyState 变为 CLOSED,且不可复用该实例。
手动重连的关键点:避免无限重试、控制间隔、区分主动关闭和异常断开。
ws.onclose = (e) => { if (e.code !== 1000) triggerReconnect() },1000 表示正常关闭new WebSocket(),别试图复用已关闭的 ws
let reconnectTimeout = null;
function connect() {
const ws = new WebSocket("wss://api.example.com/ws");
ws.onopen = () => { clearTimeout(reconnectTimeout); };
ws.onclose = (e) => {
if (e.code !== 1000) {
reconnectTimeout = setTimeout(connect, Math.min(30000, 1000 * Math.pow(2, retryCount)));
}
};
}最常见原因是后端发的数据不是 UTF-8 字符串,或者前端没处理好二进制类型。WebSocket 协议本身不规定 payload 格式,收发双方必须约定好编码和结构。
例如后端用 Uint8Array 发原始字节,但前端 ws.binaryType 还是默认的 "blob",就会导致 event.data 是无法直接读取的 Blob 对象。
TEXT)还是二进制帧(BINARY)ws.binaryType = "arraybuffer",然后用 new Uint8Array(event.data) 解析try/catch 包裹 JSON.parse(event.data),后端可能发空串或格式错乱数据WebSocket 的坑不在连接本身,而在状态管理与协议对齐。readyState 切换异步、事件触发时机、二进制类型切换、重连时序控制——这些地方一松懈,实时性就变成“偶尔通一下”。