最近需要对接一个AI大模型,后端使用SSE流式传输,要求前端正确接受这些数据,记录一下解决方法
tips:流式传输的数据是可以在浏览器开发者工具中的网络中看到的(会有一个EventSource选项卡)
-
首先的想法是使用浏览器原生的SSE接口,可以自动解析流式数据的事件名,数据等,但是EventSource构造函数不能接受header配置,如果token是放在header中的,就不能使用这个方式
-
查询资料发现fetch支持流式接收数据,示例:
const res=fetch("/api/chat");//直接使用 const reader = res.body.getReader();//获取ReadableStream const decoder = new TextDecoder(); //将Uint8Array解码 let done = false; let data = ''; while (!done) { const { value, done: doneReading } = await reader.read(); done = doneReading; if (value) { data += decoder.decode(value, { stream: true }); } }
注意,
decode
时需要加上{ stream: true }
参数,因为流式传输时,一个汉字/emoji符号会被拆成多个码点,可能正好不在同一块数据中,stream: true
可以在下次解码时自动将缓存字节与新数据块开头拼接,保证正确解码 -
如果想使用axios,需要在
axios.create
时使用adapter:"fetch"
,因为默认的xhr适配器不支持stream,然后在axios.post
时配置responseType: 'stream'
即可