You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从FastAPI向React流式传输LLM(Ollama)响应?

解决FastAPI + React流式传输LLM响应时的onopen错误

问题背景

用FastAPI对接Ollama做LLM服务,非流式请求能正常返回结果,但流式传输时,React端触发console.log("another error onopen"),无法接收流式数据;而FastAPI后端能正常打印每个流式片段。前端使用@microsoft/fetch-event-source处理SSE响应。

核心原因

  1. 后端返回的流不符合SSE规范:Server-Sent Events要求每个数据块必须以data: 前缀开头,且以\n\n结尾,否则前端无法识别为合法的SSE消息。
  2. 前端状态更新缺失:即使后端修复格式,前端也没有处理消息来更新界面显示。
  3. Content-Type判断过于严格:后端返回的Content-Type可能带有charset后缀(如text/event-stream; charset=utf-8),前端严格匹配EventStreamContentType(即text/event-stream)会导致判断失败。

修复步骤

1. 修改FastAPI后端,输出符合SSE规范的流

修改stream_answer函数,将每个LLM返回的chunk包装成SSE格式:

def stream_answer(question):
    for chunk in chain.stream(question):
        print(chunk, end='', flush=True)
        # 包装为SSE标准格式
        yield f"data: {chunk}\n\n"

2. 调整前端的Content-Type判断逻辑

在onopen回调中,用includes替代严格相等,兼容带charset的Content-Type:

async onopen(response) {
  console.log("onopen");
  console.log(response);

  if (
    response.ok &&
    response.headers.get("content-type")?.includes(EventStreamContentType)
  ) {
    return; // 连接正常
  } else if (
    response.status >= 400 &&
    response.status < 500 &&
    response.status !== 429
  ) {
    console.log("fatal error onopen");
  } else {
    console.log("another error onopen");
  }
},

3. 前端添加流式数据的状态更新

在onmessage回调中,更新answer状态,实现实时显示:

onmessage(msg) {
  console.log("onmessage");
  console.log(msg);
  if (msg.event === "FatalError") {
    throw new FatalError(msg.data);
  }
  // 累加流式片段到响应内容中
  setAnswer(prev => prev + msg.data);
},

验证

修改完成后,重新启动FastAPI和React服务:

  • 后端会继续正常打印每个chunk;
  • 前端点击按钮后,onopen会进入正常分支,onmessage会逐个接收SSE消息,界面实时更新LLM响应内容。

内容的提问来源于stack exchange,提问作者Simon1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 02:55:14