广告

前端开发必读:HTML SSE是什么?3种实时更新的Server-Sent事件用法详解

1. HTML SSE是什么?

HTML SSE,即服务器推送的事件(Server-Sent Events,简称 SSE),是一种在前端开发中用于实现服务器到客户端的单向实时推送的机制。通过浏览器原生的 EventSource 接口,客户端可以保持与服务器的长连接,接收服务器发送的 文本数据流,而无需轮询。

HTTP/1.1 的基础上实现,服务器以 text/event-stream 的内容类型持续输出数据,浏览器会把每条消息作为一个事件推送给脚本处理。自动重连分块传输、以及 简单的重试策略都是 SSE 的天然特性。

与 WebSocket 相比,SSE 是单向通信,适合服务器主动推送;对于需要双向通信的场景,通常会选择其他方案或结合技术栈。在前端日常开发中,HTML SSE 兼容性好、实现简单、开销低,尤其适用于新闻更新、股票行情、实时日志等场景。

// Node.js 简易 SSE 服务端示例
const http = require('http');
http.createServer((req, res) => {res.writeHead(200, {'Content-Type': 'text/event-stream','Cache-Control': 'no-cache','Connection': 'keep-alive'});const interval = setInterval(() => {res.write(`data: ${new Date().toISOString()}\n\n`);}, 1000);req.on('close', () => {clearInterval(interval);});
}).listen(3000);

2. 3种实时更新的Server-Sent事件用法详解

用法一:基本文本流更新

在最常见的用法中,服务器持续输出文本数据,浏览器通过 EventSource 接口接收每一条 data: ... 行并触发客户端处理逻辑。

客户端通常创建一个 EventSource 实例并监听 onmessage 事件,解析 e.data,将新行渲染到页面或状态中。

这种模式的优势在于简单、兼容性好无需轮询,非常适合需要定期更新的页面场景。

// 客户端示例
const es = new EventSource('/events');
es.onmessage = (e) => {const msg = e.data;document.getElementById('log').innerText += '更新: ' + msg + '\n';
};

用法二:事件字段与自定义事件

SSE 支持自定义事件(custom events),通过 event: <name> 行实现,结合 addEventListener 以外的事件名来触发特定处理。id 字段用于断续后续数据的顺序追踪,retry 指令用于设置重连时间。

通过这些字段,前端可以对不同类型的数据使用不同的处理逻辑,提升可维护性与可扩展性。

// 服务器端示例:发送自定义事件
res.write('event: userUpdate\n');
res.write('data: ' + JSON.stringify({ user: 'Alice', status: 'online' }) + '\n\n');
// 客户端监听自定义事件
es.addEventListener('userUpdate', (e) => {const payload = JSON.parse(e.data);console.log('用户更新:', payload);
});

用法三:与前端框架/调度器集成的实时更新

将 SSE 事件接入前端状态管理库,结合组件生命周期实现无缝的实时渲染。通过对事件进行统一的调度,可以将数据流映射到应用的状态树中,提升用户体验。

注意在实现中处理好断线重连、错误和资源清理,EventSource 提供了简单的机制来在断线后恢复连接。对于跨域场景,需要确保服务器端设置了正确的 CORS 头部,并遵循同源策略的要求。

前端开发必读:HTML SSE是什么?3种实时更新的Server-Sent事件用法详解

// React 简易示例:将 SSE 数据追加到组件状态
function SSEPanel() {const [lines, setLines] = React.useState([]);React.useEffect(() => {const es = new EventSource('/events');es.onmessage = (ev) => setLines(prev => [...prev, ev.data]);es.onerror = () => es.close();return () => es.close();}, []);return (
{lines.map((l, idx) =>
{l}
)}
); }

广告