使用 Fetch API 实现流式读取

chatgpt 逐字输出 使用fetch/eventSource/fetchEventSouce进行sse流式处理 vue chatgpt 逐字输出 使用fetch/eventSource/fetchEventSouce进行sse流式处理 阅读详情
AI摘要

博客介绍使用 Fetch API 实现流式数据输出的方法。对比了 Fetch API 和 EventSource,指出 Fetch API 具有灵活性、支持流式读取和广泛兼容等优势,而 EventSource 有仅支持 GET 请求等局限。还给出了 Fetch API 实现流式输出的步骤、代码说明及关键点,最后提及了 Deepseek 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 请求,无法传递复杂参数。

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


BUG示例:

下面是使用 Deepseek API 获取流式数据后,直接使用 JSON.parse(decoder.decode(value)) 出现的报错

在这里插入图片描述

  • Deepseek API 请求

    	// 发起 Fetch 请求
    	const response = await fetch('https://api.deepseek.com/chat/completions', {
    	    method: 'POST',
    	    headers: {
    	        'Content-Type': 'application/json',
    	        'Authorization': 'Bearer sk-ba32***************'
    	    },
    	    body: JSON.stringify({
    	        model: "deepseek-chat",
    	        messages: [{ role: "system", content: messageText }],
    	        stream: true,
    	    })
    	});
    
  • 问题出在返回的 chunk 无法直接使用 JSON.parse 解析
    在这里插入图片描述

  • chunk 返回数据,无法直接解析,出现报错
    在这里插入图片描述

  • 解决示例

     	// 获取可读流
        const reader = response.body.getReader();
        const decoder = new TextDecoder('utf-8');
        let buffer = '';
        let ohtmlStr = '';
    	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.startsWith('data: ')) {
    	            const jsonString = line.slice(6); // 去掉 'data: ' 前缀
    	            if (jsonString.trim() === '[DONE]') {
    	                console.log('Stream finished');
    	                break;
    	            }
    	            try {
    	                const data = JSON.parse(jsonString);
    	                // 提取内容并更新 UI
    	                if (data.choices && data.choices[0].delta.content) {
    	                	ohtmlStr += data.choices[0].delta.content;
    	                }
    	            } catch (error) {
    	                console.error('JSON parsing error:', error);
    	            }
    	        }
    	    }
    	}
    	// 解码缓冲区中剩余的数据(如果有)
        if (buffer) {
            const finalData = decoder.decode(); // 注意:这里不需要 { stream: true }
            console.log('Final data:', finalData);
        }
        
    
  • 测试示例
    在这里插入图片描述

    剩下的即是使用Markdown等工具,处理后在页面显示


实现chatGpt中的数据依次展示效果(Fetch+nodeJs) 流式数据获取并展示的前后端实现 阅读详情

相关推荐

Vue3项目里,如何用Fetch API替代EventSource,搞定带鉴权头的SSE通知?

本文详细介绍了在Vue3项目中使用Fetch API替代EventSource实现带鉴权头的SSE通知的方法。通过解析SSE协议格式,提供完整的Fetch API实现方案,并探讨了在Vue3中的最佳实践和性能优化技巧,帮助开发者解决实时通知系统中的鉴权难题。

weixin_42629815的博客 339

深入解析Fetch流式请求:从Chunk处理到实时渲染的完整实践

本文深入解析Fetch流式请求技术,从Chunk处理到实时渲染的完整实践。通过对比传统请求与流式请求的差异,详细介绍了ReadableStream解析流水线、AI对话流式界面构建及NDJSON流处理等核心机制,帮助开发者掌握高效处理实时数据的技术方案。

weixin_27070451的博客 229

Anolis OS 23实战:5分钟搞定AI环境配置(含NVIDIA驱动一键安装)

本文详细介绍了如何在Anolis OS 23上快速配置AI开发环境,包括NVIDIA驱动的一键安装和TensorFlow、PyTorch等AI框架的部署。通过智能硬件适配引擎和优化后的二进制包,用户可在5分钟内完成传统需要数小时的配置工作,显著提升AI项目开发效率。

weixin_30335575的博客 535

前端fetch 实现流式接口

先说说传统传输吧,我们日常接触的大多数是传统传输方式,就也是整段传输,前后端将数据一次性传送给对方;相比于传统传输方式,流式传输则采用分段的方式将要传输的数据分层n段,后端一次性传一段给前端,直到传输完成为止,当然在传输的过程中,前端也可以提前中断传输,后端收到中断传输的消息后,也不再继续往前端传输剩下没传完的数据段。当然,前端流式传输需要在后端支持分块传输的情况下才能实现。简单来说fetch 是一种 HTTP 数据请求的方式, XMLHttpRequest(以下简称 XHR)的一种替代方案。

weixin_44405693的博客 7377

akshare 布林通道策略

import datetime import pandas as pd import backtrader as bt import matplotlib.pyplot as plt from datetime import datetime import matplotlib import akshare as ak %matplotlib inline class Boll_strategy(bt.Strategy): #自定义参数,每次买入1800手 params=(('size'.

qq_26742269的博客 5338

时空数据建模的跨节点联邦图神经网络:KDD21 Cross-Node Federated Graph Neural Network for Spatio-Temporal Data Modeling

前言 联邦学习(FL)虽然已经被广泛研究,但是对复杂的时空依赖关系进行建模以提高预测能力仍然是一个开放的问题。此外目前最优的时空预测模型假定对数据的访问不受限制,忽略了对数据共享的限制。基于此,本文提了一个基于图联邦学习的时空数据模型 Cross-Node Federated Graph Neural Network (CNFGNN),该模型在跨节点联邦学习的约束下,使用基于图神经网络(GNN)的架构对底层图结构进行编码,属于结构化联邦的一种,每个本地模型利用私有数据进行学习,并保持分散性。CNFGNN

qq_56027260的博客 1810

使用fetch流式获取响应数据

流式获取一般在用于数据量比较大的情况,一次性返回会导致前端页面加载时间过长或者请求超时等问题,这时候我们就可以考虑使用流式的方式拿到部分数据并先展示,从而提升用户体验。我这里的场景是在对接chatGPT语言模型的时候采取的这种方案,因为目前的大语言的模型的结果都是需要一点点计算的,如果提出的问题比较复杂就导致响应的时间过长。

学而不思则罔 5408

SQL注入:联合查询的三个绕过技巧

在SQL注入中,可以利用科学计数法来绕过对输入的限制。例如,可以使用科学计数法来绕过对字符串长度的限制,通过将字符串拆分成多个部分并使用科学计数法来表示。此外,还可以利用数据库的特定特性或语法来替代原始的查询语句,从而执行联合查询或其他恶意操作。另外,还可以尝试利用无列名注入的技巧,通过在原始查询中使用通配符或其他方式来绕过对列名的限制,从而执行恶意操作。

qq_68163788的博客 3792

前端Javascript中Fetch请求Coze API并流式展示请求结果

因此,可能需要改用fetch,或者调整axios的配置,比如设置responseType为’stream’(但浏览器中可能不支持),或者使用onDownloadProgress回调来处理接收到的数据片段。我需要回想一下流式请求的处理方式,通常SSE(Server-Sent Events)或者使用fetch的流式读取,但用户使用的是axios,可能需要配置responseType为stream或者处理分块数据。他们可能已经能够发送消息到后端,但接收响应时是流式的,需要逐步显示数据,而不是等待整个响应完成。

警警的博客 3657

Windows 11 安装、使用 Git:下载、安装、概念、命令、分支模型

本文详细介绍了在 Windows 11 系统上安装与使用 Git 的完整流程,涵盖从官方或国内镜像下载安装包、关键安装选项配置,到 Git 核心概念(如工作区、暂存区、分支、远程仓库等)的通俗解释。同时梳理了常用命令与五种主流 Git 分支模型(如 Git Flow、GitHub Flow 等),帮助开发者根据项目规模选择合适的工作流,是面向初学者与进阶用户的实用指南。

寒水馨 · 轻量级技术文档 · hanshuixin.org 2387

十.镜头知识之畸变问题

对于理想光学系统,在一对共轭的物像平面上,像的放大率是一个常数。但是对于实际的光学系统,当视场较大或很大时,像的放大率就要随视场而异,这样就会使像相对于物体失去相似性。这种使像变形的成像缺陷称为畸变。

AIoT深度探索者 | 嵌入式系统架构师 深耕物联网(IoT)与人工智能(AI)融合技术,聚焦​​边缘计算、图像开发、低功耗通信协议​​,致力于智能硬件,关注我获取最新技术文章信息与海量资源~ 2124

前端如何通过fetch模拟调用SSE接口

本文针对SSE(Server-Sent Events)接口的三种实现方案。SSE是一种基于HTTP的单向服务端推送技术,适用于实时数据更新场景。对于GET请求,推荐使用浏览器原生EventSource API;对于POST请求,建议采用fetch+ReadableStream方案实现流式响应处理;

weixin_61877032的博客 1341

R语言 百度坐标转换至WGS84坐标

本文利用R语言封装了百度坐标转换至WGS84坐标的函数,亲测有效,提供了便捷的百度坐标转换方法。

qingchen98的博客 2135

前端使用 fetch() 流式下载.mp4视频文件,跟踪进度

使用 fetch API 进行流式下载时,可以使用对象跟踪下载进度。要么使用流读取器,要么使用 Reponse 的方法来获取结果,不能同时使用两种方法来读取相同的响应。直接获取:Response.blob() 方法返回一个 resolve 返回值为 Blob 对象的 Promise流读取:Response.body 是一个对象ReadableStream.getReader() 创建流读取器,并且会把流锁定,默认返回的是类型The。

qq_38334677的博客 3793

AUTOSAR-WdgM篇

Wdg通常有两种:一种是芯片内部自带的片内看门狗,另一种是在芯片外部通过SPI这种接口连接的片外看门狗。MCAL只负责常用的有MCU内部看门狗,片内看门狗的特点是Wdg模块是直接访问相关硬件寄存器。内部看门狗依赖于系统时钟片外看门狗属于设备抽象层负责,通常需要使用MCAL提供的其他模块(比如SPI,DIO,PWM等)来访问/控制外扩看门狗芯片。这种不能直接访问硬件寄存器。Wdg Driver:有三种模式slow mode,fast mode ,off mode。

qq_329563867的博客 5830

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

基于 fetch + ReadableStream 流式输出 实现 AI 聊天问答

本文介绍了如何通过 fetch + ReadableStream 实现 AI 聊天问答的流式响应输出,模拟 SSE 行为以支持 POST 请求和复杂参数传递。同时,结合 contenteditable 实现了支持内容高亮、代码块插入等功能的富文本输入框,并通过自定义指令实现 Vue 数据双向同步,提升交互体验。

weixin_45511682的博客 2479

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Vue 3流式输出实战:SSE协议对接AI API实现打字机效果

流式输出(Streaming Output)是一种服务器将数据分批次、实时推送到客户端的技术,其核心原理基于HTTP长连接或WebSocket等协议,允许数据像水流一样持续传输。这项技术的核心价值在于极大提升了Web应用的实时性和用户体验,尤其在处理大语言模型生成、实时日志、金融行情等需要渐进式展示内容的场景中至关重要。通过Server-Sent Events(SSE)这类HTML5标准协议,开发者可以高效实现服务器到客户端的单向实时文本流推送。本文将聚焦于如何利用Vue 3的组合式API响应式系统,结合F

weixin_34175509的博客 447

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

流式文本输出的实现方式

模拟延迟,每生成一个JSON对象后,函数将暂停1秒钟。这行代码将每个JSON对象作为字节字符串生成,并在对象之间添加两个换行符,以符合SSE的格式要求。是一个辅助函数,它确保在生成器运行时,Django的请求上下文是激活的。指定了响应的MIME类型,这样客户端浏览器会识别这是一个SSE响应。的字符串分割成多行,并将每一行作为一个单独的JSON对象逐个生成。中的每一行,代码创建一个包含这一行文本的字典。创建了一个Django响应对象,它将。将字典转换为JSON格式的字符串。函数是一个生成器,它遍历。

m0_62458145的博客 2131

fetch获取流式数据并逐个打字效果

【代码】fetch获取流式数据并逐个打字效果。

MISS_zhang_0110的博客 1222

流式输出技术实现

流式输出技术是一种能够实现数据逐步传输和实时渲染的技术,它在服务器端和客户端都有相应的实现方法。

zwjapple的专栏 755

Vue3流式调用大模型接口完整实践

const question = ref("讲一个中国龙的故事");ref:Vue3 基础响应式 API,处理字符串、数字等基础类型;底层为RefImpl实例,通过.value读写原始值question:双向绑定输入框,存储用户提问content:AI 回答渲染容器,流式模式下持续追加文本stream:布尔开关,控制接口stream参数,切换两种返回模式while (!done)是无限循环读取二进制数据流,只要服务端还在持续返回大模型 Token 分片,循环就不会停止;直到服务端推送结束标识。

A1234543211232的博客 247

手把手教你用React + Fetch API搞定DeepSeek流式回复(含完整代码和避坑点)

本文详细介绍了如何使用React和Fetch API实现DeepSeek流式对话功能,包括基础实现、核心逻辑处理、性能优化及常见问题解决方案。通过完整的代码示例和实用技巧,帮助开发者快速掌握流式数据传输技术,提升AI对话应用的用户体验。

weixin_42559413的博客 110

DeepChat代码实例:前端Vue组件对接Ollama REST API实现打字机式流式响应

本文介绍了如何在星图GPU平台上自动化部署DeepChat - 深度对话引擎镜像,快速构建本地AI对话应用。该镜像集成了Ollama与Llama 3模型,并通过前端Vue组件对接其REST API,实现了打字机式的流式响应效果,为用户提供了自然流畅的实时对话体验。

weixin_42452483的博客 455

PHP+HTML实现流式输出效果的示例详解

流式输出通常指的是在数据生成的同时逐步发送到客户端,而不是等待所有处理完成后再一次性发送。这在实时聊天应用或需要逐步显示结果的场景中很常见。

2501_94114815的博客 422

从零搭建AI对话系统:React+Spring Boot实现流式聊天应用

在现代Web应用开发中,前后端分离架构与流式数据传输是构建实时交互系统的关键技术。通过React构建组件化前端界面,结合Spring Boot提供稳健的RESTful API服务,开发者能够高效实现复杂的数据流处理与用户交互。这种技术组合不仅提升了开发效率,其非阻塞、响应式的特性尤其适合处理AI对话场景中的持续数据流,如服务器发送事件(SSE)。在实际工程中,正确处理跨域请求(CORS)、管理对话上下文以及实现可靠的错误处理机制,是保障应用稳定性的核心。本文以构建一个完整的AI对话系统为例,详细阐述了如何利

weixin_33851604的博客 394
上一篇: Vuex获取使用接口数据
下一篇: Fetch API 的工作机制及流式读取的时机
JasoncodeQvQ
博客等级 码龄7年 458粉丝 97原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值