chatGPT前端流式输出js实现三种方法—fetch、SSE、websocket

 更新时间:2024年07月27日 16:47:41   作者:又又爱拍照  
项目需要接入chatgpt提供的api,后端返回流式的字符,前端接收并实时显示,在JavaScript中,使用Stream流通常指的是处理数据流的一种方式,它们允许数据被处理成块,而不是一次性处理整个数据集,这对于处理大量数据或者来自网络请求的数据非常有用,

项目需要接入chatgpt提供的api,后端返回流式的字符,前端接收并实时显示。在JavaScript中,使用Stream流通常指的是处理数据流的一种方式。Stream可以是可读的、可写的、或者既可读又可写的。它们允许数据被处理成块,而不是一次性处理整个数据集,这对于处理大量数据或者来自网络请求的数据非常有用。

一、fetch实现stream

fetch 本身不直接支持流式输出,但你可以使用 ReadableStream 和 TextDecoder 等 Web Streams API 来实现类似的效果。

function streamOutput(msg) {
  // 发送 POST 请求
  fetch('url', {
    method:"POST",
    body:JSON.stringify({ "content": msg}),
    timeout: 0,
    dataType:"text/event-stream",
    headers:{
      "Content-Type":"application/json"
    },
  }).then(response => {
    // 检查响应是否成功
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    // 返回一个可读流
    return response.body;
  }).then(body => {
    disableLoading();
    const reader = body.getReader();
    // 读取数据流
    function read() {
      return reader.read().then(({ done, value }) => {
        // 检查是否读取完毕
        if (done) {
          console.log('已传输完毕');
          return;
        }
        // 处理每个数据块
        console.log('收到的数据:', value);
        // 继续读取下一个数据块
        read();
      });
    }
    // 开始读取数据流
    read();
  }).catch(error => {console.error('Fetch error:', error);});
}

二、SSE实现(只支持GET请求)

在 SSE 中,浏览器通过发送 HTTP GET 请求到服务器上特定的 SSE 端点(endpoint),然后服务器通过该连接发送事件(event)和相关数据到客户端,故SSE 主要使用 GET 请求。EventSource不支持发送请求头,如果需要发送请求头则要用EventSourcePolyfill。

在使用EventSourcePolyfill前需要引入 Server-Sent Events (SSE) 的 JavaScript 库。

引入方式一:npm或yarn

npm install event-source-polyfill
yarn add event-source-polyfill

在js文件中引入

import EventSource from 'event-source-polyfill';

引入方式二:eventsource

下载仓库:https://github.com/Yaffle/EventSource
注意:进入src文件下载所需eventsource.js或eventsource.min.js文件,引入时注意路径,如果是jsp文件用绝对路径

<script type="text/javascript" src="/path/eventsource.js"></script>
function streamOutput() {
	  // 创建 EventSourcePolyfill连接,如果不需要发送请求头可以使用EventSource即可
	const eventSource = new EventSourcePolyfill('url',{
		headers:{
      		"Content-Type":"application/json"
    	}
	});
	// 处理 SSE 消息
	eventSource.onmessage = function (event) {
	  console.log('接收SSE的消息:', event.data);
	  // 在这里处理接收到的流式数据
	};
	// 处理 SSE 连接打开事件
	eventSource.onopen = function (event) {
	  console.log('SSE连接完成:', event);
	};
	// 处理 SSE 连接关闭事件
	eventSource.onclose = function (event) {
	  console.log('SSE连接关闭:', event);
	};
	// 处理 SSE 错误事件
	eventSource.onerror = function (error) {
	  console.error('SSE EventSource error:', error);
	};
}

三、websocket实现(url必须为ws或wss开头的接口)

WebSocket 是一种全双工通信协议,允许客户端和服务器之间进行实时的双向通信,并且支持POST请求。但是值得注意的是WebSocket只支持ws或wss开头的接口。WebSocket 握手时并没有提供直接设置请求头的标准方法,它的握手阶段是由浏览器自动处理的,因此你不能直接在创建 WebSocket 连接时设置请求头,但可以通过通过 URL 参数传递的方式传递信息。

function streamOutput(msg) {
	 const socket = new WebSocket('url');
	// 连接打开时触发
	socket.addEventListener('open', event => {
	  console.log('WebSocket连接完成:', event);
	  // 处理接收到的消息
	  socket.addEventListener('message', event => {
	    console.log('接收消息:', event.data);
	    // 在这里处理接收到的流式数据
	  });
	});
	// 连接关闭时触发
	socket.addEventListener('close', event => {
	  console.log('WebSocket连接关闭:', event);
	});
	// 处理错误时触发
	socket.addEventListener('error', error => {
	  console.error('WebSocket error:', error);
	});
}

四、总结

相关文章

  • 原生js实现放大镜

    原生js实现放大镜

    本文主要分享了原生js实现放大镜效果的示例代码,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • js判断浏览器版本以及浏览器内核的方法

    js判断浏览器版本以及浏览器内核的方法

    这篇文章主要介绍了js判断浏览器版本以及浏览器内核的方法,可实现针对各个浏览器的判断,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-01-01
  • js中遍历对象的属性和值的方法

    js中遍历对象的属性和值的方法

    下面小编就为大家带来一篇js中遍历对象的属性和值的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • 微信小程序实现底部弹出模态框

    微信小程序实现底部弹出模态框

    这篇文章主要为大家详细介绍了微信小程序实现底部弹出模态框,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟)

    BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟)

    这篇文章主要介绍了BOM系列第三篇之定时器应用(时钟、倒计时、秒表和闹钟) 的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-08-08
  • js实现ifram取父窗口URL地址的方法

    js实现ifram取父窗口URL地址的方法

    这篇文章主要介绍了js实现ifram取父窗口URL地址的方法,是javascript操作window.parent对象非常典型的应用技巧,需要的朋友可以参考下
    2015-02-02
  • 微信小程序自定义菜单导航实现楼梯效果

    微信小程序自定义菜单导航实现楼梯效果

    在html开发中,我们可以用到a标签锚点实现,jq的动画相结合实现类似效果。在框架中vant UI框架也为我们实现了这一效果。接下来通过本文给大家介绍微信小程序自定义菜单导航实现楼梯效果,感兴趣的朋友一起看看吧
    2021-12-12
  • 利用JavaScript实现时间戳功能的5种方法详解

    利用JavaScript实现时间戳功能的5种方法详解

    在现代软件开发中,时间戳是记录时间的重要手段,在JavaScript中,通过不同的方法可以获取当前的时间戳,这篇文章主要介绍了利用JavaScript实现时间戳功能的5种方法,需要的朋友可以参考下
    2025-10-10
  • JavaScript中valueOf函数与toString方法深入理解

    JavaScript中valueOf函数与toString方法深入理解

    基本上,所有JS数据类型都拥有valueOf和toString这两个方法,null除外。它们俩解决javascript值运算与显示的问题,本文将详细介绍,有需要的朋友可以参考下
    2012-12-12
  • 微信小程序自定义导航栏(模板化)

    微信小程序自定义导航栏(模板化)

    这篇文章主要为大家详细介绍了微信小程序自定义导航栏(模板化),文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11

最新评论