EventSource
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since January 2020.
EventSource
接口是 web 内容与服务器发送事件通信的接口。
一个 EventSource
实例会对 HTTP 服务器开启一个持久化的连接,以 text/event-stream
格式发送事件,此连接会一直保持开启直到通过调用 EventSource.close()
关闭。
一旦连接开启,来自服务端传入的消息会以事件的形式分发至你代码中。如果接收消息中有一个 event 字段,触发的事件与 event 字段的值相同。如果不存在 event 字段,则将触发通用的 message
事件。
与 WebSocket 不同的是,服务器发送事件是单向的。数据消息只能从服务端到发送到客户端(如用户的浏览器)。这使其成为不需要从客户端往服务器发送消息的情况下的最佳选择。例如,对于处理如社交媒体状态更新、消息来源(news feed)或将数据传递到客户端存储机制(如 IndexedDB 或 web 存储)之类的,EventSource
无疑是一个有效方案。
警告:当不使用 HTTP/2 时,服务器发送事件(SSE)受到打开连接数的限制,这个限制是对于浏览器的,并且设置为非常低的数字(6),打开多个选项卡时可能会特别痛苦。在 Chrome 和 Firefox 中,这个问题已被标记为“不会修复”。这个限制是每个浏览器和域名的,这意味着你可以在所有标签页中打开 6 个 SSE 连接到 www.example1.com
,以及另外 6 个 SSE 连接到 www.example2.com
(来源:Stackoverflow)。当使用 HTTP/2 时,最大并发 HTTP 流的数量是由服务器和客户端协商的(默认为 100)。
构造函数
EventSource()
-
创建一个新的
EventSource
,用于从指定的 URL 接收服务器发送事件,可以选择开启凭据模式。
实例属性
此接口从其父接口 EventTarget
继承属性。
EventSource.readyState
只读-
一个代表连接状态的数字。可能值是
CONNECTING
(0
)、OPEN
(1
)或CLOSED
(2
)。 EventSource.url
只读-
一个表示事件源的 URL 字符串。
EventSource.withCredentials
只读-
一个布尔值,表示
EventSource
对象是否使用跨源资源共享(CORS)凭据来实例化(true
),或者不使用(false
,即默认值)。
实例方法
此接口也从其父接口 EventTarget
继承了方法。
EventSource.close()
-
关闭连接(如果有),并将
readyState
属性设置为CLOSED
。如果连接已经关闭,则该方法不执行任何操作。
事件
示例
在这个基本的例子中,创建了一个 EventSource
来从服务器接收未命名的事件;一个名为 sse.php
的页面负责生成这些事件。
const evtSource = new EventSource("sse.php");
const eventList = document.querySelector("ul");
evtSource.onmessage = (e) => {
const newElement = document.createElement("li");
newElement.textContent = `message: ${e.data}`;
eventList.appendChild(newElement);
};
每个接收到的事件都会导致我们的 EventSource
对象的 onmessage
事件处理程序运行。它会创建一个新的 <li>
元素,并将消息的数据写入其中,然后将新元素附加到文档中已有的列表元素中。
备注:你可以在 Github 上找到完整的示例——使用 PHP 语言的简单 SSE 示例。
要监听具名事件,你需要为每种类型的事件添加一个监听器。
const sse = new EventSource("/api/v1/sse");
/*
* 这将仅监听类似下面的事件
*
* event: notice
* data: useful data
* id: someid
*/
sse.addEventListener("notice", (e) => {
console.log(e.data);
});
/*
* 同理,以下代码将监听具有字段 `event: update` 的事件
*/
sse.addEventListener("update", (e) => {
console.log(e.data);
});
/*
* “message”事件是一个特例,因为它可以捕获没有 event 字段的事件,
* 以及具有特定类型 `event:message` 的事件。
* 它不会触发任何其他类型的事件。
*/
sse.addEventListener("message", (e) => {
console.log(e.data);
});
规范
Specification |
---|
HTML Standard # the-eventsource-interface |
浏览器兼容性
BCD tables only load in the browser