Bootstrap

SSE之fetchEventSource学习

        通过之前的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博客

;