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

瀏覽器相容性

另見