WebSocket需服务端配合、状态管理、错误重连和协议设计;常见问题包括URL协议错误(须用ws/wss)、连接拒绝、关闭异常及JSON序列化要求;应检查readyState、实现心跳与指数退避重连,并重视消息ID与离线队列。

WebSocket 不是“用一下就行”的 API,它需要服务端配合、连接状态管理、错误重连和消息协议设计。直接调用 new WebSocket() 只是第一步,真正卡住人的地方在连接维持和数据解析。
WebSocket 连接失败的常见原因和检查点
页面报 Failed to construct 'WebSocket': The URL's scheme must be either 'ws' or 'wss'?说明你用了 http:// 或 https:// 开头的地址。WebSocket 必须用 ws://(开发)或 wss://(生产)。
其他高频问题:
-
net::ERR_CONNECTION_REFUSED:后端没启动,或端口没暴露(比如 Node.js 服务监听localhost:3000,但前端连的是ws://127.0.0.1:8080) -
net::ERR_CONNECTION_CLOSED:服务端主动断开,或防火墙/Nginx 没配置 WebSocket 升级头(Upgrade: websocket+Connection: Upgrade) - 控制台无报错但
onopen不触发:检查服务端是否正确响应了 HTTP Upgrade 请求,很多轻量 server(如 Pythonhttp.server)根本不支持
如何安全地发送和接收 JSON 消息
WebSocket 的 send() 只接受 string、ArrayBuffer、Blob,不能直接传对象。硬塞 send({msg: "hi"}) 会触发 TypeError。
立即学习“Java免费学习笔记(深入)”;
标准做法是统一序列化/反序列化:
云模块_YunMOK网站管理系统采用PHP+MYSQL为编程语言,搭载自主研发的模块化引擎驱动技术,实现可视化拖拽无技术创建并管理网站!如你所想,无限可能,支持创建任何网站:企业、商城、O2O、门户、论坛、人才等一块儿搞定!永久免费授权,包括商业用途; 默认内置三套免费模板。PC网站+手机网站+适配微信+文章管理+产品管理+SEO优化+组件扩展+NEW Login界面.....目测已经遥遥领先..
const ws = new WebSocket("wss://api.example.com/ws");
ws.onmessage = (event) => {
try {
const data = JSON.parse(event.data);
console.log("收到", data);
} catch (e) {
console.warn("非 JSON 消息", event.data);
}
};
function sendMsg(obj) {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify(obj));
} else {
console.error("WebSocket 未就绪,当前状态", ws.readyState);
}
}
注意:ws.readyState 必须检查。状态值为 0(CONNECTING)、1(OPEN)、2(CLOSING)、3(CLOSED),别在 0 或 3 时发消息。
为什么 onerror 不总被触发,以及怎么真正捕获异常
onerror 是事件处理器,但它不捕获所有错误——比如网络闪断、服务端崩溃、DNS 失败,往往只触发 onclose,且 event.code 可能是 1006(abnormal closure)这种模糊码。
更可靠的保活策略:
- 自己实现心跳:定时
send({ type: "ping" }),服务端回{ type: "pong" },超时未响应则手动ws.close()后重连 - 重连不要用
setTimeout简单递归,避免雪崩;建议指数退避(第一次 1s,第二次 2s,第三次 4s…) - 记录
ws.url和最后一次成功通信时间,重连时带上?last_ts=171xxxx方便服务端补发离线消息
浏览器兼容性和降级风险
现代浏览器都支持 WebSocket,但要注意:
- iOS Safari 在后台标签页中会暂停 WebSocket 连接(即使没关),
onclose可能延迟数分钟才触发 - 某些企业内网代理会拦截
Upgrade请求,导致连接卡在CONNECTING状态(readyState === 0) - 没有真正的降级方案:HTTP long-polling 实现复杂、延迟高、服务器压力大,除非业务明确要求 IE9 支持,否则别写备用轮询逻辑
真实项目里,连接不可靠是常态。比起纠结“怎么连上”,更该花时间设计消息 ID、去重机制、离线缓存队列——这些才是实时体验不崩的关键。









