EventSource

EventSource 接口是网页内容与 服务器发送事件 交互的接口。

EventSource 实例会打开到 HTTP 服务器的持久连接,服务器会以 text/event-stream 格式发送 事件。该连接会一直保持打开状态,直到通过调用 EventSource.close() 关闭为止。

EventTarget EventSource

连接打开后,来自服务器的传入消息将以事件的形式传递到您的代码中。如果传入消息中存在 event 字段,则触发的事件与 event 字段的值相同。如果不存在 event 字段,则会触发一个通用的 message 事件。

WebSockets 不同,服务器发送事件是单向的;也就是说,数据消息只从服务器传递到客户端(例如用户的 Web 浏览器)。这使得它们成为不需要以消息形式将数据从客户端发送到服务器的情况下的理想选择。例如,EventSource 是一种用于处理社交媒体状态更新、新闻提要或将数据传递到像 客户端存储 机制(如 IndexedDBWeb 存储)的有效方法。

警告:不通过 HTTP/2 使用时,SSE 会受到打开连接数量上限的限制,这在打开多个选项卡时尤其让人头疼,因为限制是每个浏览器的,并且设置的数字非常低(6)。该问题在 ChromeFirefox 中被标记为“不会修复”。此限制是每个浏览器 + 域的,这意味着您可以对 www.example1.com 的所有选项卡打开 6 个 SSE 连接,并对 www.example2.com 打开另外 6 个 SSE 连接。(来自 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。如果连接已经关闭,则该方法不执行任何操作。

事件

error

当与事件源的连接无法打开时触发。

message

当从事件源接收数据时触发。

open

当与事件源的连接打开时触发。

此外,事件源本身可以发送带有 event 字段的消息,这将创建以该值为键的临时事件。

示例

在此基本示例中,创建一个 EventSource 来接收来自服务器的无名事件;一个名为 sse.php 的页面负责生成事件。

js
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 演示

要监听命名事件,您需要为每个发送的事件类型创建一个监听器。

js
const sse = new EventSource("/api/v1/sse");

/*
 * This will listen only for events
 * similar to the following:
 *
 * event: notice
 * data: useful data
 * id: someid
 */
sse.addEventListener("notice", (e) => {
  console.log(e.data);
});

/*
 * Similarly, this will listen for events
 * with the field `event: update`
 */
sse.addEventListener("update", (e) => {
  console.log(e.data);
});

/*
 * The event "message" is a special case, as it
 * will capture events without an event field
 * as well as events that have the specific type
 * `event: message` It will not trigger on any
 * other event type.
 */
sse.addEventListener("message", (e) => {
  console.log(e.data);
});

规范

规范
HTML 标准
# the-eventsource-interface

浏览器兼容性

BCD 表格仅在启用 JavaScript 的浏览器中加载。

另请参阅