> 技术文档 > 前端接收流式数据的完整方案(SSE/WebSocket/Fetch API)_前端sse

前端接收流式数据的完整方案(SSE/WebSocket/Fetch API)_前端sse


一、流式数据

什么是流式数据?

  • 数据分多次传输,无需等待完整内容即可开始处理
  • 典型场景:实时日志、股票行情、AI生成内容(如ChatGPT逐字输出)
二、5种主流实现方案
1. Server-Sent Events (SSE)

特点

  • 单向通信(服务端→客户端)
  • 基于HTTP协议,自动重连
  • 兼容性:除IE外主流浏览器均支持

代码示例

const eventSource = new EventSource(\'/api/stream\');// 接收消息eventSource.onmessage = (event) => { console.log(\'New data:\', event.data);};// 自定义事件类型eventSource.addEventListener(\'stockUpdate\', (e) => { const data = JSON.parse(e.data); updateStockChart(data);});// 错误处理eventSource.onerror = () => { console.error(\'Stream failed\');};

服务端要求

Content-Type: text/event-streamCache-Control: no-cacheConnection: keep-alive
2. WebSocket

特点

  • 全双工通信
  • 适合高频双向数据交换

代码示例

const socket = new WebSocket(\'wss://api.example.com/stream\');socket.onopen = () => { socket.send(\'subscribe:stocks\'); // 发送初始指令};socket.onmessage = (event) => { const data = JSON.parse(event.data); renderRealTimeData(data);};socket.onclose = () => { console.log(\'Disconnected\');};

协议对比

维度 SSE WebSocket 协议 HTTP WS/WSS 方向 单向 双向 二进制支持 仅文本 支持二进制 自动重连 ✅ ❌
3. Fetch API + Streams API

特点

  • 精细控制数据流
  • 适合处理大文件下载

代码示例

const response = await fetch(\'/api/large-file\');const reader = response.body.getReader();while (true) { const { done, value } = await reader.read(); if (done) break; // 处理分块数据(Uint8Array) const text = new TextDecoder().decode(value); console.log(\'Chunk:\', text);}

应用场景

  • 逐行读取CSV文件
  • 视频流处理
4. XMLHttpRequest (旧式方案)

兼容性方案

const xhr = new XMLHttpRequest();xhr.open(\'GET\', \'/api/stream\');xhr.onprogress = (event) => { const newData = xhr.responseText.substr(lastIndex); processData(newData);};xhr.send();
5. Web Workers + Stream(CPU密集型处理)

优化方案

// 主线程const worker = new Worker(\'stream-worker.js\');worker.postMessage({ cmd: \'start\', url: \'/api/stream\' });// worker.jsself.onmessage = async (e) => { const response = await fetch(e.data.url); const reader = response.body.getReader(); while (true) { const { done, value } = await reader.read(); self.postMessage({ data: value }); if (done) break; }};
三、关键问题解决方案
  1. 数据完整性

    • 使用分隔符(如\\n\\n
    • 实现ACK确认机制(WebSocket)
  2. 性能优化

// 防抖处理高频数据let buffer = [];const debounceRender = _.debounce(() => { render(buffer); buffer = [];}, 100);socket.onmessage = (event) => { buffer.push(event.data); debounceRender();};

3.错误恢复

// SSE自动重连eventSource.onerror = () => { setTimeout(() => new EventSource(url), 5000);};
四、现代框架集成
React示例(SSE + Hook)
function useStream(url) { const [data, setData] = useState(\'\'); useEffect(() => { const es = new EventSource(url); es.onmessage = (e) => { setData(prev => prev + e.data); }; return () => es.close(); }, [url]); return data;}// 使用const logs = useStream(\'/api/log-stream\');
Vue示例(WebSocket)
export default { data() { return { stockData: [] } }, created() { this.socket = new WebSocket(\'wss://stocks.com\'); this.socket.onmessage = (e) => { this.stockData.push(JSON.parse(e.data)); }; }, beforeUnmount() { this.socket.close(); }}
五、调试工具
  1. Chrome DevTools

    • Network面板查看SSE/WS连接
    • 流数据实时监控
  2. 测试工具

# 模拟SSE服务printf \"data: test1\\n\\n\" | nc -l 8080
六、服务端配合要求
技术 响应头 数据格式 SSE text/event-stream data: {...}\\n\\n WebSocket Upgrade: websocket 二进制/文本 Fetch Transfer-Encoding: chunked 分块编码

上面这些方案可以实现: ✅ 实时聊天应用
✅ 金融行情看板
✅ 大文件逐块处理
✅ AI生成内容流式展示