一、认识EventSource
EventSource(也称为Server-Sent Events,简称SSE)是HTML5中的一种新的API,用于实现服务器端向客户端推送事件。其数据主要基于HTTP协议进行传输,并且数据帧必须编码成UTF-8的格式。
eventSource是单向通信的,只能从服务器端向客户端发送数据。如果你需要双向通信(即客户端和服务器之间可以相互发送数据),那么你可能需要使用WebSocket或其他技术。
二、项目中使用
而 eventSource
只能由服务器向客户端发送消息,项目中常用的请求方式又get和post方式,对于没有请求要求的情况,短文本的情况使用浏览器提供的api即可。
1.使用get方式
不需要安装插件,直接创建EventSource对象,通过EventSource对象连接服务,连接服务以后就可以接受服务推送的消息。
//定义一个EventSource对象,传入请求地址URL
const eventSource = new EventSource('url')
// 与事件源的连接刚打开时触发
eventSource.onopen = function (e) {
console.log(e, "连接刚打开时触发");
};
// 后端返回信息,格式可以和后端协商
eventSource.onmessage = function (e) {
console.log(e);
};
// 连接失败
eventSource.onerror = function (e) {
console.log(e);
eventSource.close(); // 关闭连接
};
// 关闭连接
eventSource.close();
注意:使用浏览器提供的本地EventSource服务,无法获取连接状态编码。
2.使用post方式请求
使用post的方式请求eventSource,常用的就是通过fetchEventSource这个库来实现,借助第三方库的fetchEventSource方法连接服务,通过AbortController 对象可以关闭服务
安装fetch-event-source插件
npm install --save @microsoft/fetch-event-source
本地使用fetch-event-source
import { fetchEventSource } from '@microsoft/fetch-event-source';
const ctrlAbout = new AbortController();
const { signal } = ctrlAbout;
fetchEventSource(Url, {
method: 'POST',
headers: {
"Content-Type": 'application/json',
"Accept": 'text/event-stream'
},
body: JSON.stringify(data),
onmessage(event) {
console.info(event.data);
// 在这里操作流式数据
},
onclose(ee) {
// 关闭流
}
onerror(error) {
console.info(error);
//返回流报错
}
})
如果您想要手动中断流式返回,可以通过以下几个步骤来实现
- 获取AbortController实例:首先,您需要创建一个
AbortController
的实例。这个实例将用于发送中断信号。const controller = new AbortController(); const { signal } = controller;
- 传递信号到fetchEventSource:在调用
fetchEventSource
时,将signal
作为参数传递给它。这样,您就可以通过这个信号来控制请求的中断。fetchEventSource(url, { signal: signal, // ... 其他配置项 });
- 中断请求:当您需要中断流式返回时,调用
AbortController
的abort
方法。controller.abort();
调用
abort
方法后,如果流还在进行中,它将被中断,fetchEventSource
的连接将被关闭。
注意:
当在前端使用AbortController
的abort()
方法被设计为只能调用一次来取消与之关联的活动请求。一旦您调用了ctrlAbout.abort()
,与该AbortController
相关联的AbortSignal
的aborted
属性就会被设置为true
,表示请求已经被取消。
如果您尝试再次调用ctrlAbout.abort()
,它不会有任何效果,因为第一次调用已经将请求标记为已取消。如果您需要再次取消相同的请求或者启动一个新的请求并有能力取消它,您需要创建一个新的AbortController
实例。例如:
// 创建一个新的AbortController实例
const ctrlAbout = new AbortController();
// 使用fetchEventSource发起请求,并传入新的AbortSignal
fetchEventSource(url, { signal: ctrlAbout.signal });
// 当需要取消请求时
ctrlAbout.abort(); // 第一次调用将取消请求
// 如果需要再次发起请求并保留取消的能力,需要再次创建AbortController
const newCtrlAbout = new AbortController();
fetchEventSource(url, { signal: newCtrlAbout.signal });
// 然后可以使用新的控制器来取消新的请求
newCtrlAbout.abort(); // 对新请求有效
每次您想要发起一个新的可取消的请求时,都应该创建一个新的AbortController
实例。这样,您就可以独立地控制每个请求的取消操作。
其他:
项目中遇到: SyntaxError: Unexpected end of JSON input 的报错内容,很有可能是当前返回的json体和当前接口的json体不匹配