如何解决前端JavaScript处理流式响应的坑
作者:小周同学:
axios是一个支持node端和浏览器端的易用、简洁且高效的http库,这篇文章主要介绍了如何解决前端JavaScript处理流式响应的坑,文中通过代码介绍的非常详细,需要的朋友可以参考下
给使用 JavaScript 的同学提个醒!
浏览器端处理流式响应,想要完美体验 请使用 Fetch API。
Axios 无法使用stream来直接处理真正的流式响应(但 Node.js 中可以使用 stream),这与浏览器底层 HTTP 请求实现的限制有关。
为什么浏览器中的 Axios 不能直接处理流?
1. 底层机制差异
- Node.js 环境:Axios 使用 Node.js 的 http 模块,天然支持流式传输(responseType:
‘stream’),数据可以逐块(chunk)接收。 - 浏览器环境:浏览器端 Axios 基于 XMLHttpRequest,而 XMLHttpRequest 的 responseType
属性不允许设为 stream,合法值仅有: arraybuffer | blob | document | json | text。
即使服务端返回流式响应(如 text/event-stream 或分块数据),浏览器也无法通过 Axios 直接以流的形式逐块解析数据。Axios 在浏览器中只能一次性接收完整响应,再通过字符串或文本处理模拟“流式效果”。
2. 如果必须使用 Axios
- 可以通过更改 responseType: ‘text’ 和 手动分块处理 模拟流式效果,但存在以下问题:
数据完整性风险:依赖服务端分块的准确性,需维护缓冲区(buffer)处理不完整数据。 性能损失:需手动分割字符串,效率低于原生流式处理。
<script> // fetch 请求,stream 流式响应 async function fetchStreaming () { const response = await fetch('http://192.168.21.24:11434/api/chat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, // 请求传递给 ollama 数据 body: JSON.stringify({ model: 'deepseek-r1:32b', messages: [ { "role": "user", "content": "北京天安门看升旗仪式怎么预约?" } ] }) }) if (!response.body) { throw new Error('Response body is null') } // 读取数据流 const reader = response.body.getReader() // 文本解码器 const decoder = new TextDecoder() let buffer = '' while (true) { const { done, value } = await reader.read() if (done) break buffer += decoder.decode(value, { stream: true }) const lines = buffer.split('\n') buffer = lines.pop() || '' for (const line of lines) { if (line.trim()) { try { const data = JSON.parse(line) // 实时输出 console.log(data.message.content) } catch (err) { console.error('解析错误:', err) } } } } } fetchStreaming() </script>
实现效果
(处理成这样之后需要前端来优化下界面样式区分思考过程和答案)
总结
到此这篇关于如何解决前端JavaScript处理流式响应坑的文章就介绍到这了,更多相关JS处理流式响应坑内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!