在使用 eventSource 时发现,其只支持 GET 请求,如果我们接口是 POST,那么我们如何去实现它呢?
EventSource
EventSource 也称为 SSE(Server-Sent Events),是服务器推送的一个网络事件接口,一个 EventSource 会对 http 服务开启一个持久化链接,它发送的事件格式是text/stream
,开启 EventSource 事件后,它会一直保持开启状态,直到达到某种条件后将其关闭。
具体使用如下
const eventSource = new EventSource('/sse');
eventSource.onopen = (event) => {
console.log('连接成功');
};
eventSource.onmessage = (event) => {
console.log('返回数据');
if('达到关闭的条件') {
eventSource.close();
}
};
eventSource.onerror = (error) => {
console.log('eventSource error');
};
eventSource.onclose = (event) => {
console.log('关闭连接成功');
};
其默认为 GET 方法,无法将其改为 POST,那我们怎么办呢?这时候就要使用插件去实现了。
使用插件实现 POST 的 eventSource 请求
安装插件 npm i --save @microsoft/fetch-event-source
import { fetchEventSource } from '@microsoft/fetch-event-source';
fetchEventSource(Url, {
method: 'POST',
headers: {
"Content-Type": 'application/json',
},
body: JSON.stringify(data),
onopen(event) {
console.log('连接成功');
},
onmessage(event) {
console.log('返回数据');
},
onclose() {
// 数据返回结束时触发
console.log('关闭连接成功');
},
onerror() {
console.log('eventSource error');
}
})
这样就实现了使用 POST 请求 eventSource,不过使用这个插件还有个问题:当发送请求且暂未触发 onopen
事件前,离开当前窗口时会自动被取消,状态变为 canceled
,等再次切换回请求页面时会主动发起请求。(目前暂未寻到解决方案,各位大佬有啥解决方案可以多多留言)
通过 fetch 实现 接口返回的 text/event-stream
数据
const result = await fetch(`${url}`, {
method: 'POST',
body: JSON.stringify(params),
headers: {
'Content-Type': 'application/json'
},
})
const reader = result.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
// 数据流已经处理完毕
break;
}
// 将字节数据转换为文本
const chunk = new TextDecoder('utf-8').decode(value);
processLine(chunk);
}
const processLine = () => {
// 处理数据
}