EventSource 实现前端异步推流更轻量,无需握手、天然支持重连与断点续传,但需严格遵循 SSE 规范:前端用 withCredentials 携带凭证,监听 message/error/open 事件;服务端返回 text/event-stream、每条消息以 data: 开头并双换行结尾,可选 id/retry/event 字段;复杂场景推荐 fetchEventSource 库;框架中需避免响应式批量更新破坏流式效果。

用 EventSource 实现前端异步推流,确实比 WebSocket 更轻量——它不需握手、不维护双向状态、天然支持重连与断点续传,且全程走标准 HTTP,部署零额外配置。关键在于理解它的设计边界,并在前后端配合中踩准几个核心点。
前端只需 3 行有效代码,但必须写对
原生 EventSource 构造函数只接受一个 URL(GET 请求),不支持自定义请求头或 POST 方法。若需携带 token 或跨域凭证,必须显式启用 withCredentials:
const es = new EventSource('/api/stream', { withCredentials: true });- 监听
message事件处理常规数据;监听error捕获连接异常;监听open确认连接建立 - 浏览器自动带上
Last-Event-ID头重连,前提是服务端返回了id:字段
服务端响应格式不能出错,否则前端收不到
SSE 要求响应头和消息体严格符合规范:
- 响应头必须包含:
Content-Type: text/event-stream、Cache-Control: no-cache、Connection: keep-alive - 每条消息以
data:开头,结尾必须是两个换行符\n\n(单个\n表示未结束,浏览器会等待) - 可选字段:
event:定义事件类型、id:标识消息序号(用于断线重连)、retry:设置重连间隔(毫秒)
需要认证或复杂请求时,改用 fetchEventSource
当原生 EventSource 不够用(比如要加 Authorization 头、动态 query 参数、或需细粒度控制连接生命周期),推荐使用 @microsoft/fetch-event-source 库:
立即学习“前端免费学习笔记(深入)”;
- 它基于 Fetch API,完全兼容现代浏览器,支持 headers、method、body(虽 SSE 本质不用 body,但便于统一封装)
- 调用方式简洁:
fetchEventSource('/api/stream', { headers: { 'Authorization': 'Bearer xxx' }, onmessage: handler }) - 错误恢复、重连策略、abort 控制都内置,无需手动轮询或定时器兜底
Vue/React 等框架中要注意流式渲染陷阱
框架的响应式更新机制可能缓冲多次 onmessage 回调,导致“一次性刷出全部内容”,失去逐字流式效果:
- Vue 项目中,确保 Webpack/Vite 的
compress配置为false(否则 gzip 压缩会合并小块响应) - React 中避免直接拼接字符串更新 state,改用
useRef+innerHTML或textContent手动追加 - 所有场景下,服务端发送频率不宜过快(如


















