通过之前的SSE学习Server-Sent Events 学习-CSDN博客和SSE之eventSourceSSE之EventSource学习-CSDN博客这两篇博客的学习,我们可以发现浏览器自带的EventSource API还存在一定的限制:
- 唯一允许传入的参数是 withCredentials;
- 不能传入请求正文,必须在 URL 中对执行请求所需的所有信息进行编码,在大多数浏览器中限制为 2000 个字符;
- 不能传入自定义请求标头;
- 只能发出 GET 请求 ,无法指定其他方法;
- 如果连接被切断就无法控制重试策略,浏览器会默默地重试几次,然后就会停止,但这对于任何一种健壮的应用程序来说无疑都不够好;
综上所述,EventSource的限制都来源它不支持POST请求,为了解决上面所陈述的那些限制,我们可以通过fetch的方式完成post相关操作。具体可以使用开源组件fetchEventSource来完成需求:GitHub - Azure/fetch-event-source: A better API for making Event Source requests, with all the features of fetch()
首先,让我们进行安装:
npm install @microsoft/fetch-event-source
使用效果:
import { fetchEventSource } from '@microsoft/fetch-event-source';
var that =this;
const ctrl = new AbortController()
fetchEventSource('/api/sse', {
method: 'POST',
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
},
body: JSON.stringify({
foo: 'bar'
}),
signal: ctrl.signal,
async onopen(response) {//建立连接的回调
if (response.ok && response.headers.get('content-type') === EventStreamContentType) {
return; // everything's good
} else if (response.status >= 400 && response.status < 500 && response.status !== 429) {
// client-side errors are usually non-retriable:
throw new FatalError();
} else {
throw new RetriableError();
}
},
onmessage(msg) { //接收一次数据段时回调,因为是流式返回,所以这个回调会被调用多次
// if the server emits an error message, throw an exception
// so it gets handled by the onerror callback below:
if (msg.event === 'FatalError') {
throw new FatalError(msg.data);
}
},
onclose() {//正常结束的回调
that.controller.abort() //关闭连接
},
onerror(err) {//连接出现异常回调
// 必须抛出错误才会停止
if (err instanceof FatalError) {
throw err; // rethrow to stop the operation
} else {
// do nothing to automatically retry. You can also
// return a specific retry interval here.
}
}
});
参考与推荐:
@microsoft/fetch-event-source - npm (npmjs.com)
chatgpt 逐字输出 使用fetch/eventSource/fetchEventSouce进行sse流式处理-CSDN博客