目录
一、fetch
二、EventSource
1.直接使用EventSource
2.event-source-polyfill插件
在网络请求中,流(stream)表示持续接收数据的过程,SSE (Server-Sent Events),服务器使用流信息向浏览器推送信息,能够实时地在客户端更新数据而无需刷新页面。不用等待整个响应完成后一次性获取。SSE它基于 HTTP 协议,目前除了 IE/Edge,其他浏览器都支持。
使用SSE是在用vue对接智谱.AI的时候,对接智谱.AI使用HTTP调用,调用方式选择sse-invoke : SSE 调用的时候才能实现打字机效果,加强用户体验,缩短用户等待时间。还可以实现天气预报推送等功能。使用SSE,服务器响应的MIME类型必须是Accept:text/event-stream
vue实现SSE有两种方式,对接智谱.AI需要使用第一种,使用fetch发送post请求。
一、fetch
// 用来终止fetch请求
window.controller = new AbortController();
let signal = window.controller.signal;
fetch(addressStr, {
method: "POST",
headers: 你的请求头,
signal,//用来中止fetch请求
mode: "cors", // cors、no-cors 或者 same-origin 解决跨域问题
credentials: "include", // omit、include、same-origin(默认)。为了在当前域名内自动发送 cookie,必须提供这个选项
body: JSON.stringify(你的数据),
})
.then((response) => {
const reader = response.body.getReader();
const decoder = new TextDecoder("utf-8");
let buffer = "";
function processStreamResult(result) {
const chunk = decoder.decode(result.value, { stream: !result.done });
buffer += chunk;
//逐条解析后端返回数据
const lines = buffer.split("\n");
buffer = lines.pop();
// 判断是否中断此条消息生成,设置一个标志位,flag为true继续输出为false中断
if (flag) {
lines.forEach((line) => {
if (line.trim().length > 0) {
if (line.match(/^data*/gi)) {
chatStr += line.slice(5);
//将结果赋值给你需要展示输出结果的地方
console.log(chatStr)
}
if (line.match(/^data:*$/gi)) {
//添加回车,展示的时候才会换行
chatStr += "\n";
}
if (line.match(/^meta*/gi)) {
//此条消息输出结束,添加你的逻辑代码
}
}
});
} else {
//中断此条消息生成后,你的逻辑代码
}
if (!result.done) {
return reader.read().then(processStreamResult);
}
}
return reader.read().then(processStreamResult);
})
.catch((error) => {
console.error("Error:", error);
});
//在需要中断fetch请求的地方调用
window.controller.abort();
二、EventSource
1.直接使用EventSource
一个 EventSource 实例会对 HTTP 服务开启一个持久化的连接,以text/event-stream 格式发送事件,会一直保持开启直到被要求关闭。这种方法不能添加请求头。
//判断浏览器是否支持SSE
if('EventSource' in window){
// 建立SSE连接,创建EventSource实例,支持跨越
let source = new EventSource(url, { withCredentials: true });
// 连接创建成功的回调事件
source.onopen = function (event) {
console.log("连接成功")
};
// 连接创建失败的回调事件
source .onerror = function (event) {
//执行错误的页面逻辑,关闭连接
console.log("连接失败")
source .close();
}
// 接受到数据的回调事件
source .onmessage = function (event) {
if (event.data == "[DONE]") {
//执行完成的页面逻辑
condole.log(event.data)
source.close();
}else{
}
}
}
2.event-source-polyfill插件
是使用插件封装后的EventSource,它可以在不支持EventSource的浏览器中提供类似的功能,并且支持设置请求头,例如token等,但是对接智谱.AI不能用这种方式,因为它发送的是get请求,但智谱.AI要求是POST请求。
首先 npm install event-source-polyfill
import EventSource from 'eventsource-polyfill';
// 创建一个新的EventSource对象,并设置请求头
const eventSource = new EventSource('你的url', {
headers: {
'Authorization': 'your-token',
}
});
// 连接成功
eventSource.onopen = function(event) {
console.log( event.data);
};
eventSource.onmessage = function(event) {
console.log( event.data);
};
//连接失败
eventSource.onerror = function(error) {
console.error('Error:', error);
};