vue 3 中 axios 不原生支持 sse,推荐 get 用 eventsource,post 或需自定义头时用 axios 配合 stream 或 ondownloadprogress 手动解析流式数据。

Vue 3 中 Axios 本身不原生支持 SSE(Server-Sent Events),但它可以和 SSE 的核心机制配合使用——关键在于:**Axios 负责发起请求(尤其是需要携带 body 或自定义 header 的 POST 场景),而事件解析逻辑需手动实现;若只需 GET + 标准头,优先用原生 EventSource 更简洁可靠。**
为什么不能直接用 axios.get(...).then() 接收 SSE?
Axios 默认将整个响应体作为一次性 payload 解析(如 JSON 或 text),而 SSE 是持续流式响应(text/event-stream),数据分块到达、以 data:、event:、id: 等格式组织。直接等 .then() 会等到连接关闭才触发,失去“实时性”。
方案一:GET 请求 → 用 EventSource(推荐)
适用于标准 SSE 接口(GET + 无 body)。它原生支持自动重连、事件类型区分、ID 管理,且 Vue 3 中可轻松封装为响应式服务:
- 在
onMounted中创建new EventSource(url, { withCredentials: true })(如需 Cookie 或跨域凭据) - 监听
onmessage处理通用事件,或addEventListener('update', handler)处理自定义事件名 - 将接收到的
event.data解析为 JSON(若后端发的是data: {"msg":"ok"})并更新 ref 或 reactive 数据 - 在
onBeforeUnmount中调用eventSource.close()避免内存泄漏
方案二:POST 请求或需传 body → Axios + 流式读取(responseType: 'stream')
当 SSE 接口要求 POST 方法(例如带 prompt 的 AI 流式响应)、或需发送 JSON body、自定义 header(如鉴权 token)时,EventSource 无法满足,此时用 Axios 发起请求,并手动读取流:
- 设置
responseType: 'stream'(注意:仅现代浏览器支持,需确认目标环境) - 从
response.data获取ReadableStream,用getReader()和TextDecoder按块解码 - 按换行符
\n切分缓冲区,逐行识别data:行,提取内容并JSON.parse()(若为合法 JSON) - 保留未结束的一行到下次处理,避免跨 chunk 截断(例如
data: {"a":和"b"}\n分属两块)
方案三:POST 请求但环境不支持 stream → Axios + onDownloadProgress(兼容旧版)
针对不支持 ReadableStream 的浏览器(如旧版 Edge),可用 Axios 的 onDownloadProgress 回调模拟流式接收:
- 配置
method: 'POST'、headers: { 'Accept': 'text/event-stream', 'Content-Type': 'application/json' } - 在
onDownloadProgress中通过progressEvent.event.target.responseText获取已接收的完整文本 - 每次回调都重新按行分割、提取新
data:条目(需自行去重或跳过已处理行,可用 lastEventId 或简单计数辅助) - 注意该方式无法区分 chunk 边界,且
responseText可能包含重复内容,适合对精度要求不高的日志类推送
补充要点
无论哪种方式,都建议:
- 后端返回必须设 Content-Type: text/event-stream 且禁用缓存(Cache-Control: no-cache、Connection: keep-alive)
- 前端处理前校验 event.data 是否为空或非法 JSON,避免解析报错中断流
- 对接错误时(onerror 或 catch),记录日志并考虑指数退避重连
- 在 Vue 组件中用 onUnmounted 清理所有连接和定时器,防止内存泄漏
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










