eventsource 支持自定义事件需服务端发送 event: myevent\ndata: ...\n\n,客户端用 addeventlistener('myevent') 捕获;chrome 120+、firefox 115+、safari 17.4+ 支持,旧版 safari 需用 message 事件 + json 解析 type 字段兜底。

EventSource 默认只支持 message、open、error 三种事件类型
直接调用 addEventListener('myevent', handler) 不会触发——EventSource 的规范不支持任意命名的自定义事件类型。它底层只解析以 event: 开头的字段,并将对应名称映射为 CustomEvent 实例,但前提是浏览器必须按标准实现该行为,而目前 Chrome、Firefox、Safari 均**不派发非内置类型的事件**。
真正能监听到自定义事件名的唯一方式:服务端发送 event: 字段 + data: 内容
客户端无需额外注册,只要服务端响应中包含 event: myevent 行,且后续有 data:,浏览器就会自动触发 myevent 类型的事件(前提是该事件名不是 message/open/error)。
实操要点:
- 服务端响应体每条消息必须以
event: myevent\n开头,后跟data: {...}\n\n(注意两个换行) - 客户端用
source.addEventListener('myevent', e => console.log(e.data))即可捕获,e.data是字符串,需手动JSON.parse() - 若服务端漏写
event:行,或写成EVENT:(大小写敏感),事件不会被识别 - Chrome 120+ 已支持该行为;Firefox 115+ 支持;Safari 17.4+ 才开始稳定支持,旧版 Safari 会静默忽略
监听不到自定义事件?先检查 EventSource.readyState 和网络响应格式
常见失败不是代码写错,而是协议没对齐。调试时重点看两点:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 打开 DevTools → Network → 点击 SSE 请求 → 查看 **Preview 或 Response** 标签页,确认内容是纯文本、每条消息以
event:和data:分隔,且末尾有双换行 - 在控制台执行
source.readyState,值为0(CONNECTING)说明连接未建立,1(OPEN)才可能收事件;若长期为0,可能是服务端未设置Content-Type: text/event-stream或未禁用响应缓冲 - 不要依赖
onmessage捕获自定义事件——它只响应无event:行的默认消息
兼容性兜底方案:统一用 message 事件 + 解析 data 字段中的 type 字段
当目标环境包含旧版 Safari 或需要强兼容时,放弃 event: 方案,改用语义化数据结构:
data: {"type":"user_update","payload":{"id":123,"name":"Alice"}}
然后在 message 回调里做分发:
source.addEventListener('message', e => {
try {
const msg = JSON.parse(e.data);
if (msg.type === 'user_update') handleUserUpdate(msg.payload);
else if (msg.type === 'order_created') handleOrder(msg.payload);
} catch (err) {
// 忽略非法 JSON
}
});
这个模式没有浏览器兼容问题,但失去了原生事件调度的简洁性,也丧失了事件冒泡和 stopPropagation 能力。
真正难的不是写监听器,而是让服务端输出符合规范的流式响应——少一个换行、多一个空格、错一个冒号,前端就收不到任何东西。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










