前端如何接受流式数据(SSE)

52 阅读1分钟

最近需要对接一个AI大模型,后端使用SSE流式传输,要求前端正确接受这些数据,记录一下解决方法

tips:流式传输的数据是可以在浏览器开发者工具中的网络中看到的(会有一个EventSource选项卡)

  1. 首先的想法是使用浏览器原生的SSE接口,可以自动解析流式数据的事件名,数据等,但是EventSource构造函数不能接受header配置,如果token是放在header中的,就不能使用这个方式

  2. 查询资料发现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可以在下次解码时自动将缓存字节与新数据块开头拼接,保证正确解码

  3. 如果想使用axios,需要在axios.create时使用adapter:"fetch",因为默认的xhr适配器不支持stream,然后在axios.post时配置responseType: 'stream'即可