EventSource

Baseline 广泛可用 *

此特性已相当成熟,可在许多设备和浏览器版本上使用。自 ⁨2020 年 1 月⁩ 起,所有主流浏览器均已支持。

* 此特性的某些部分可能存在不同级别的支持。

注意:此功能在 Web Workers 中可用。

EventSource 接口是 Web 内容与 服务器发送事件 的接口。

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

EventTarget EventSource

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

WebSockets 不同,服务器发送事件是单向的;也就是说,数据消息在一个方向上传输,从服务器到客户端(例如用户的 Web 浏览器)。这使得它们成为不需要从客户端向服务器发送消息的理想选择。例如,EventSource 是处理社交媒体状态更新、新闻源或将数据输入到 客户端存储 机制(如 IndexedDBWeb Storage)的有用方法。

警告:不在 HTTP/2 上使用时,SSE 会受到打开连接数量上限的限制,当打开多个选项卡时,这可能会特别痛苦,因为限制是每个浏览器,并且设置为一个非常低的数字(6)。在 ChromeFirefox 中,此问题已被标记为“不会修复”。此限制是每个浏览器 + 域,这意味着您可以在所有选项卡中为 www.example1.com 打开 6 个 SSE 连接,为 www.example2.com 再打开 6 个 SSE 连接。(来自 Stack Overflow)。使用 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: some-id
 */
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

浏览器兼容性

另见