SSE接口切换页签/页面,接口重复调用问题

问题: sse接口重复执行

对接Deepseek时,使用@microsoft/fetch-event-source 联调SSE接口
后端同事提出个奇怪的问题,接口老是重复执行,我又没有复现,经过来回测试,
终于复现了,切换浏览器页签时,就会多一个sse接口调用,如下图:

在这里插入图片描述

分析:

  1. 调用栈Initator里不是我们的代码引起的,而是@microsoft/fetch-event-source库,由此可见是该库的某配置或者sse事件的特性

  2. 查阅@microsoft/fetch-event-source库的配置项参数,发现有 openWhenHidden

请添加图片描述
3. 尝试配置为true,代码生效,再次切换浏览器页签,也不重复调用

溯源找原因

  1. 查阅 mdn EventSource 资料,并未发现有openWhenHidden配置

在前端中调用 SSE(Server-Sent Events)接口,可以使用浏览器提供的 `EventSource` API。SSE 是一种服务器向客户端推送事件的技术,适用于实时更新数据的场景,比如股票价格、聊天消息等。 下面是一个完整的示例,展示如何在前端调用一个 SSE 接口并处理接收到的数据: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>SSE Example</title> </head> <body> <h1>Messages from Server:</h1> <div id="messages"></div> <script> // 创建 EventSource 实例,连接到服务器端的 SSE 接口 const eventSource = new EventSource("https://example.com/sse"); // 监听服务器发送的消息 eventSource.addEventListener("message", function(event) { const newElement = document.createElement("div"); newElement.textContent = "Message: " + event.data; document.getElementById("messages").appendChild(newElement); }); // 可以监听其他自定义事件,例如 'update' eventSource.addEventListener("update", function(event) { const newElement = document.createElement("div"); newElement.textContent = "Update: " + event.data; document.getElementById("messages").appendChild(newElement); }); // 错误处理 eventSource.addEventListener("error", function(event) { console.error("EventSource failed:", event); }); // 关闭连接(可选) // eventSource.close(); </script> </body> </html> ``` ### 代码解释: 1. **创建 `EventSource` 实例**: - `new EventSource("https://example.com/sse")`:连接到指定的 SSE 接口。 - 这个接口必须返回 `text/event-stream` 类型的内容。 2. **监听事件**: - `eventSource.addEventListener("message", ...)`:监听默认的 `message` 事件,接收服务器推送的数据。 - `event.data`:包含从服务器接收到的数据。 3. **自定义事件**: - 除了默认的 `message` 事件,你还可以监听服务器发送的自定义事件,比如 `update`。 4. **错误处理**: - `error` 事件会在连接失败或发生错误时触发。 5. **关闭连接**: - 如果需要停止接收事件,可以调用 `eventSource.close()`。 ### 后端支持(Node.js 示例): 以下是一个简单的 Node.js 后端实现,用于提供 SSE 接口: ```javascript const express = require('express'); const app = express(); app.get('/sse', (req, res) => { res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); // 模拟每隔 5 秒发送一条消息 let count = 0; const interval = setInterval(() => { res.write(`data: ${JSON.stringify({ message: `Hello from server! ${count}` })}\n\n`); count++; }, 5000); // 当客户端断开连接时清除定时器 req.on('close', () => { clearInterval(interval); res.end(); }); }); app.listen(3000, () => { console.log('Server is running on port 3000'); }); ``` ### 后端代码解释: 1. **设置响应头**: - `Content-Type: text/event-stream`:告诉浏览器这是一个 SSE 流。 - `Cache-Control: no-cache` 和 `Connection: keep-alive`:确保连接不会被缓存或中断。 2. **发送消息**: - 使用 `res.write()` 发送消息,格式为 `data: <message>\n\n`。 - 这里每 5 秒发送一次消息。 3. **清理资源**: - 当客户端断开连接时,通过 `req.on('close', ...)` 清除定时器并结束响应。 --- ### 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值