onmessage仅处理无event字段的默认消息;它只响应不带event:前缀的data:消息,不自动解析json,仅提供data/origin/lasteventid属性,不触发event:自定义事件,且不自动重连。

onmessage 回调只处理无 event 字段的默认消息
onmessage 是 EventSource 实例上最直接的事件处理器,但它有明确限制:仅响应服务器发送的、不带 event: 前缀的消息。一旦服务端在响应中写了 event: update 或 event: ping,这条消息就**不会触发 onmessage**,而必须用 addEventListener('update', ...) 显式监听。
- 服务端输出
data: hello\n\n→ 触发onmessage - 服务端输出
event: user_login\ndata: {"id":123}\n\n→ 不触发onmessage,需addEventListener('user_login', ...) - 即使
data字段是 JSON 字符串,onmessage也只返回字符串,不会自动JSON.parse
onmessage 的 event 对象只有 data/origin/lastEventId 三个可用属性
别指望它像 MessageEvent(Web Worker)那样有 source 或 ports。在 SSE 场景下,event.data 是唯一真正承载业务数据的字段;event.origin 是服务端响应头 Access-Control-Allow-Origin 所允许的源,不是当前页面 URL;event.lastEventId 是服务端通过 id: 行下发的序号,用于断线重连时告诉服务端“我已收到 ID=42 之前的所有消息”。
- 若服务端没发
id:行,event.lastEventId为空字符串 -
event.origin在同域时是完整协议+主机+端口(如https://api.example.com),不是相对路径 - 不要对
event.data做信任解析——它可能是空格、换行、甚至空字符串,需先event.data.trim()再判断
onmessage 不会自动重连,错误后需手动干预
onmessage 本身不控制连接生命周期。当网络抖动或服务端关闭连接,EventSource 会按规范自动尝试重连(默认 3 秒),但期间所有失败都走 onerror,且 readyState 会经历 0 → 0(CONNECTING → CLOSED)循环。此时 onmessage 完全静默,你无法从中感知断连。
- 务必同时设置
onerror,并在其中检查eventSource.readyState === 0来确认是否已断开 - 不要在
onerror里直接new EventSource(...)—— 这会绕过内置重连机制,造成连接爆炸 - 如果需要自定义重连间隔,应在构造前设
eventSource.addEventListener('error', ...)并在内部调用eventSource.close()后延时重建
兼容性差的 IE 系列必须降级处理
IE 11 及更早版本完全不支持 EventSource,也没有 onmessage 属性。检测不能只靠 typeof EventSource !== 'undefined',因为某些 polyfill 会挂载构造函数但不实现全部行为。
- 安全检测写法:
if (window.EventSource && 'onmessage' in EventSource.prototype) - 降级方案优先选长轮询(
fetch+setTimeout),而非 XHR 流式读取——后者在 IE 中难以稳定截断 - 若用 polyfill(如
eventsource-polyfill),注意它通常不支持withCredentials和自定义lastEventId
onmessage 不是“万能接收器”,它只认裸 data:。一旦服务端加了 event:,前端却还守着 onmessage,消息就彻底消失了。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











