EventSource仅支持服务端单向推送,因协议未定义发送能力且无send()方法,无法发送心跳或用户操作;WebSocket需手动实现指数退避重连,实例不可复用;SSE在代理/CDN下易断连,需服务端定时发心跳;兼容性上Safari 15.4+才支持withCredentials,企业内网可能禁用ws协议。

只收服务端数据,用 EventSource 就够了;一旦要发消息(哪怕只是心跳、确认、点赞),必须切到 WebSocket。
为什么 EventSource 不能发消息?
这不是浏览器限制,而是协议本身没定义发送能力——EventSource 接口压根没有 send() 方法。你写 eventSource.send(...),JS 会直接报 TypeError: eventSource.send is not a function。常见错误是误以为它像 fetch 一样可读可写,结果卡在“怎么把用户操作同步给后端”这一步。
真实场景中,如果用 EventSource 做日志流,还得额外配一个 fetch('/api/log-action', { method: 'POST' }) 处理用户点击“清空日志”这类动作,两套连接逻辑并存,状态难统一。
WebSocket 断开后不会自动重连
和 EventSource 不同,WebSocket 的 onclose 触发后连接就彻底没了,浏览器不会帮你重试。不手动实现重连,用户切后台再回来,连接大概率已断。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 必须自己写重连逻辑,推荐用指数退避(如首次等 1s,失败则 2s、4s、8s…)
- 设最大重试次数(比如 5 次),避免网络恢复前疯狂建连打挂服务端
- 注意
WebSocket实例不可复用:重连得new WebSocket(url),旧实例调close()后不能再用
SSE 在代理或 CDN 下容易意外断连
EventSource 依赖 HTTP 长连接,而很多反向代理(Nginx 默认 60s)、CDN(Cloudflare 默认 100s)会主动关闭空闲连接。现象是:每过一两分钟就触发一次重连,控制台频繁打印 EventSource connected,但服务端其实一直在线。
解决方法不是调大超时,而是让服务端定期发心跳:
- 每 15–30 秒写一条注释行:
data: \n\n(注意两个换行) - 或发空事件:
event: heartbeat\ndata: {}\n\n - Nginx 需显式配置:
proxy_read_timeout 300;,且确保proxy_buffering off;
客户端选型时最容易忽略的兼容性点
EventSource 在 Safari 15.4+ 才支持 withCredentials,老版本跨域带 cookie 会失败;WebSocket 则从一开始就不走 CORS,靠服务端的 Origin 校验,但需要明确响应 Sec-WebSocket-Accept。
更隐蔽的问题是:某些企业内网环境禁用 ws:// 协议,但允许 http://,这时 EventSource 反而能通,WebSocket 直接被拦截——别只看浏览器支持表,得测真实部署环境。

















