一文吃透前端流式输出:Fetch Stream/SSE 全方案落地
·
在 AI 聊天机器人、实时日志、大屏监控、长文本渲染等场景中,流式输出(Streaming) 已经成为标配能力。它让页面不必等待全部数据返回,而是收到一块、渲染一块,极大降低首屏等待时间、减少内存占用、提升用户体验。
本文从原理 → API → 多框架实现 → 优化 → 排错,完整覆盖前端流式输出全链路,可直接用于生产环境。
目录
3.1 Fetch + ReadableStream 标准实现
一、流式输出核心原理
1.1 什么是流式输出?
流式输出:服务端使用 HTTP 分块传输编码(Chunked Transfer Encoding),将数据拆分为多个块(chunk)持续推送;前端边接收边解析边渲染,不等待完整响应。
对比传统请求:
- 传统:等待全部数据返回 → 一次性渲染
- 流式:来一块渲染一块 → 连续展示
1.2 核心优势
- 首屏延迟极低
- 内存占用更小(不缓存全量数据)
- 用户体验更流畅(打字机、实时日志)
- 适合超长文本、AI 回复、数据流推送
1.3 关键技术支撑
- HTTP/1.1
Transfer-Encoding: chunked - 浏览器
Streams API(ReadableStream) Fetch+TextDecoder- SSE(Server-Sent Events)
- WebSocket(双向流场景)
二、三种主流方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Fetch + ReadableStream | 最灵活、支持 POST / 请求头、可取消 | 代码稍多 | AI 对话、自定义流、需要权限头 |
| SSE(EventSource) | 极简、自动重连、原生支持 | 只支持 GET、无法自定义头 | 日志推送、通知、简单单向流 |
| WebSocket | 全双工、极强控制力 | 重、需服务端改造 | 聊天、高实时双向通信 |
主流首选:AI 打字机 → Fetch Stream简单推送 → SSE
三、原生 JavaScript 实现(最通用)
3.1 Fetch + ReadableStream 标准实现
async function startFetchStream(url, onChunk, onFinish) {
const controller = new AbortController()
try {
const response = await fetch(url, {
method: 'POST',
signal: controller.signal,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: 'hello' })
})
if (!response.body) throw new Error('不支持流式')
const reader = response.body.getReader()
const decoder = new TextDecoder('utf-8', { stream: true })
while (true) {
const { done, value } = await reader.read()
if (done) break
const chunk = decoder.decode(value)
onChunk?.(chunk)
}
onFinish?.()
} catch (err) {
console.error('流异常:', err)
}
return controller
}
3.2 使用示例
const output = document.getElementById('output')
startFetchStream(
'/api/stream',
(chunk) => {
output.innerHTML += chunk
output.scrollTop = output.scrollHeight
},
() => console.log('流结束')
)
四、SSE 极简实现(适合纯推送)
function startSSE(url, onMessage) {
const es = new EventSource(url)
es.onmessage = (e) => {
if (e.data === '[DONE]') {
es.close()
return
}
onMessage?.(e.data)
}
es.onerror = () => es.close()
return es
}
使用:
startSSE('/api/sse', (chunk) => {
output.innerHTML += chunk
})
五、Vue3 实战封装(生产可用)
<!-- StreamOutput.vue -->
<template>
<div class="stream-box" ref="box">{{ content }}</div>
</template>
<script setup>
import { ref, onUnmounted } from 'vue'
const content = ref('')
const box = ref(null)
let controller = null
async function startStream() {
content.value = ''
controller = await startFetchStream(
'/api/chat',
(chunk) => {
content.value += chunk
box.value.scrollTop = box.value.scrollHeight
}
)
}
onUnmounted(() => {
controller?.abort()
})
</script>
六、React 实战封装
import { useState, useEffect, useRef } from 'react'
export function StreamComponent() {
const [text, setText] = useState('')
const ref = useRef(null)
const controllerRef = useRef(null)
const start = async () => {
setText('')
controllerRef.current = startFetchStream('/api/stream', (chunk) => {
setText(prev => prev + chunk)
ref.current.scrollTop = ref.current.scrollHeight
})
}
useEffect(() => {
return () => controllerRef.current?.abort()
}, [])
return <div ref={ref} className="stream">{text}</div>
}
七、高级优化策略(必看)
7.1 防止中文乱码
const decoder = new TextDecoder('utf-8', { stream: true })
stream: true允许跨块拼接字符,避免中文截断乱码。
7.2 渲染节流(防止卡顿)
let buffer = []
let timer = null
function pushChunk(chunk) {
buffer.push(chunk)
if (!timer) {
timer = setTimeout(() => {
onChunk(buffer.join(''))
buffer = []
timer = null
}, 30)
}
}
7.3 可取消流(避免内存泄漏)
const controller = new AbortController()
fetch(url, { signal: controller.signal })
// 取消
controller.abort()
7.4 XSS 防护
function escapeHtml(s) {
return s.replace(/[&<>"']/g, c => ({ '&':'&','<':'<','>':'>','"':'"',"'":''' }[c]))
}
八、高频问题与排查
8.1 常见问题
- 流不生效:服务端未返回
Transfer-Encoding: chunked - 中文乱码:缺少
{ stream: true } - 无法跨域:服务端缺少 CORS 头
- 浏览器卡住:未做渲染节流
- 内存上涨:未取消流、未清理定时器
8.2 调试方法
- Chrome F12 → Network → Response 查看分块
- 确保服务端不断开连接
- 使用
curl -N url测试流是否正常
九、总结
前端流式输出的核心三要素:
- 协议:HTTP Chunked
- API:ReadableStream + TextDecoder
- 渲染:逐块追加、自动滚动、节流优化
最佳实践选型:
- AI 对话 / 富交互流 → Fetch Stream
- 日志 / 通知推送 → SSE
- 双向高强度通信 → WebSocket
掌握本文内容,可轻松实现 ChatGPT 式打字机、实时日志、大屏数据流、大文件解析等所有前端流式场景。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)