当前位置: 首页 > news >正文

使用 Fetch API 实现流式读取

例如:要实现 Ollama 接口调用后,文字逐步输出(即流式数据),推荐使用 Fetch API 并设置 stream: true,而不是使用 EventSource。以下是详细解释和实现方法:

为什么选择 Fetch API 而不是 EventSource?

1. Fetch API 的优势

  • 灵活性:Fetch API 支持自定义请求头和请求体,适合需要传递复杂参数(如 model 和 prompt)的场景。

  • 流式读取:通过 response.body.getReader(),可以逐步读取响应数据,实现逐字输出。

  • 广泛支持:Fetch API 是现代浏览器的标准 API,兼容性良好

2. EventSource 的局限性

  • 仅支持 GET 请求:EventSource 是基于 HTTP GET 请求的,无法直接传递复杂的请求体(如 JSON 数据)。

  • 单向通信:EventSource 只能接收服务器发送的数据,无法像 Fetch API 那样灵活地控制请求和响应。

  • 适用场景有限:EventSource 更适合服务器主动推送数据的场景(如实时通知),而不是逐步返回生成内容。

使用 Fetch API 实现流式数据输出

以下是完整的实现步骤和代码示例:

1. 设置 stream: true

在请求体中设置 stream: true,告诉 Ollama 以流式方式返回数据。

2. 逐步读取响应

使用 response.body.getReader() 逐步读取响应数据,并通过 TextDecoder 解码。

3. 实时更新页面

将每次读取的数据实时更新到页面上,实现逐字输出效果。


<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Ollama Stream Response</title>
</head>
<body>
  <h1>Ollama Stream Response</h1>
  <button id="ask-btn">Ask Ollama</button>
  <pre id="response"></pre>

  <script>
    document.getElementById('ask-btn').addEventListener('click', async () => {
      // 发起 Fetch 请求
      const response = await fetch('http://localhost:11434/api/generate', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          model: 'llama2', // 模型名称
          prompt: 'Tell me a story about a dragon.', // 输入提示
          stream: true, // 启用流式响应
        }),
      });

      // 获取可读流
      const reader = response.body.getReader();
      const decoder = new TextDecoder();
      const responseElement = document.getElementById('response');

      // 逐步读取数据
      while (true) {
        const { done, value } = await reader.read();
        if (done) break; // 如果流结束,退出循环

        // 解码并处理数据
        const chunk = decoder.decode(value);
        const data = JSON.parse(chunk);

        // 逐步更新页面内容
        responseElement.textContent += data.response;
      }
    });
  </script>
</body>
</html>

代码说明

  1. Fetch 请求:

    • 设置 stream: true,启用流式响应。
    • 传递 model 和 prompt 参数。
  2. 流式读取:

    • 使用 response.body.getReader() 获取可读流。
    • 通过 TextDecoder 解码二进制数据为字符串。
  3. 逐步更新:

    • 每次读取的数据是一个 JSON 对象,包含 response 字段。
    • 将 response 字段的内容逐步追加到页面中。

关键点

  1. 流式响应:
    • 确保在请求体中设置 stream: true。
    • 使用 response.body.getReader() 逐步读取数据。
  2. 数据格式:
    • 每个数据块是一个 JSON 对象,包含 response 字段(生成的内容)。
  3. 性能优化:
    • 对于长文本生成,流式响应可以显著提升用户体验,避免长时间等待。
  4. 错误处理:
    • 在实际项目中,建议添加错误处理逻辑(如网络错误、JSON 解析错误等)。

总结

  • 推荐使用 Fetch API:通过设置 stream: true 并逐步读取响应数据,可以实现流式输出。

  • EventSource 不适用:因为 EventSource 仅支持 GET 请求,无法传递复杂参数。

  • 逐步更新页面:通过实时更新页面内容,可以实现逐字输出的效果。

相关文章:

  • 单片机学习笔记——入门51单片机
  • 在windows下通过wsl工具管理Linux子系统
  • UDS诊断、ECU刷写、自动化测试、车联网测试、DTC故障注入测试、坏境测试、可靠性测试、压力测试、性能测试等
  • 计算机四级 - 数据库原理(操作系统部分)- 第5章「内存管理」
  • QT Quick(C++)跨平台应用程序项目实战教程 3 — 项目基本设置(窗体尺寸、中文标题、窗体图标、可执行程序图标)
  • C++:类和对象(含各编译器对编译过程的优化解释)详解[后篇]
  • Neo Gamma 机器人在 GTC 2025 上的突破性进展与表现分析
  • JVM运行时数据区内部结构难记?一个例子优化记忆
  • 避坑指南 | 阿里云服务器centos7上MySQL部署优化指南
  • C++之模板进阶
  • 亮相AWE2025,MOVA以科技重塑生活,以美学沟通世界
  • 标贝科技入选2025年市级数据要素市场化配置改革“揭榜挂帅”名单
  • 2025蓝桥杯备赛Day1——B2109 统计数字字符个数
  • 微信小游戏:跳一跳,自动化操作
  • 4.6--入门知识扫盲,路径追踪与路由误导:Tracert攻击 vs ICMP重定向攻击(包你看一遍全记住)
  • squirrel语言全面介绍
  • JAVA学习--java数组--打印稀疏数组和稀疏数组的还原
  • React基础语法速览
  • 每日一题力扣2960.统计已测试设备c++
  • 从零开始:使用 Cython + JNI 在 Android 上运行 Python 算法
  • 中国恒大:清盘人向香港高等法院申请撤回股份转让
  • 媒体和打拐志愿者暗访长沙一地下代孕实验室,警方已控制涉案人员
  • 何立峰:中方坚定支持多边主义和自由贸易,支持世贸组织在全球经济治理中发挥更大作用
  • 马克龙称法英正与乌克兰商议“在乌部署欧洲军队”
  • 著名蒙古族音乐学者马•斯尔古愣逝世,享年86岁
  • 气象干旱黄色预警继续:陕西西南部、河南西南部等地特旱