HTML5 SSE
SSE(Server-Sent Events,服务器推送事件)是 HTML5 提供的服务器向浏览器单向推送数据的方案:网页和服务器维持一条 HTTP 连接,服务器一有新数据就主动发过来,页面无需轮询或刷新。给网页做行情、通知、实时日志时,SSE 简单又实用。
什么是 SSE
- 方向单一:只支持服务器 → 浏览器,适合订阅推送类功能。
- 基于 HTTP:不需要新协议,普通 Web 服务器就能实现,容易穿透防火墙。
- 自动重连:连接意外断开后,浏览器会自动重新连接服务器。
- 文本数据:默认传输 UTF-8 文本,结合 JSON 字符串可传结构化数据。
浏览器端:EventSource 对象
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>SSE 实时消息</title>
</head>
<body>
<h3>实时消息</h3>
<ul id="news"></ul>
<script>
// 1. 创建 EventSource,参数是服务器推送接口地址
var source = new EventSource("/api/news");
// 2. message 事件:每收到一条数据就触发一次
source.onmessage = function (event) {
var li = document.createElement("li");
li.textContent = event.data; // 服务器推送的内容
document.getElementById("news").appendChild(li);
};
// 3. 连接出错时浏览器会自动重连,这里仅做提示
source.onerror = function () {
console.log("连接异常,准备自动重连……");
};
</script>
</body>
</html>
在浏览器中显示为:网页"实时消息"标题下不断追加新列表项,每项就是一条最新推送;前提是 /api/news 接口已按下方格式提供服务。
服务器端返回格式
服务器把响应头设为 text/event-stream,并按固定格式持续输出文本,每个数据块之间用空行分隔:
Content-Type: text/event-stream
Cache-Control: no-cache
data: 第一条消息
data: 第二条消息
每个 data: 行对应触发一次 message 事件,浏览器读取的 event.data 就是 data: 之后的内容。
数据块的字段
data:数据内容;一个数据块可写多行 data,浏览器会用换行把它们拼接起来。id:消息编号;断线重连时浏览器会带上它,方便服务器接着推送。event:自定义事件名;页面用 addEventListener 监听同名事件。retry:设置浏览器重连间隔(毫秒)。
给消息指定事件名的写法:
<script>
var source = new EventSource("/api/tips");
// 监听自定义事件 news(服务器端用 event: news 声明)
source.addEventListener("news", function (event) {
console.log("收到公告:" + event.data);
});
</script>
SSE 与 WebSocket 的区别
| 对比项 | SSE | WebSocket |
|---|---|---|
| 通信方向 | 单向:服务器 → 浏览器 | 双向实时 |
| 底层协议 | 普通 HTTP | 独立的 ws/wss 协议 |
| 自动重连 | 浏览器内置 | 需要自己实现 |
| 数据格式 | 文本 | 文本和二进制都支持 |
| 适用场景 | 通知、行情、订阅 | 聊天、游戏、协同编辑 |
小结:SSE 用 EventSource 接收服务器单向推送,实现简单、自带重连,很适合"服务器有更新就通知页面"的功能;需要双向通信时再选 WebSocket。