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.

* Some parts of this feature may have varying levels of support.

Note: This feature is available in Web Workers.

Giao diện EventSource là giao diện mà nội dung web dùng để làm việc với server-sent events.

Một thể hiện EventSource mở một kết nối bền vững đến một máy chủ HTTP, máy chủ này sẽ gửi events theo định dạng text/event-stream. Kết nối sẽ vẫn mở cho đến khi được đóng bằng cách gọi EventSource.close().

EventTarget EventSource

Khi kết nối đã mở, các thông điệp đến từ máy chủ sẽ được chuyển đến mã của bạn dưới dạng các sự kiện. Nếu thông điệp đến có trường event, sự kiện được kích hoạt sẽ có cùng giá trị với trường đó. Nếu không có trường event, một sự kiện chung message sẽ được kích hoạt.

Không giống như WebSockets, server-sent events là một chiều; nghĩa là các thông điệp dữ liệu chỉ được truyền theo một hướng, từ máy chủ đến client, chẳng hạn như trình duyệt web của người dùng. Điều này khiến chúng trở thành lựa chọn rất phù hợp khi không cần gửi dữ liệu từ client lên máy chủ dưới dạng thông điệp. Ví dụ, EventSource là cách hữu ích để xử lý các thứ như cập nhật trạng thái mạng xã hội, luồng tin tức, hoặc đưa dữ liệu vào cơ chế lưu trữ phía client như IndexedDB hoặc web storage.

Warning: Khi không dùng qua HTTP/2, SSE gặp giới hạn về số lượng kết nối mở tối đa. Điều này đặc biệt khó chịu khi mở nhiều tab, vì giới hạn này tính theo trình duyệt và được đặt ở mức rất thấp (6). Vấn đề này đã được đánh dấu là "Won't fix" trong ChromeFirefox. Giới hạn này tính theo trình duyệt + miền, nghĩa là bạn có thể mở 6 kết nối SSE trên tất cả các tab tới www.example1.com và thêm 6 kết nối SSE khác tới www.example2.com. (trích từ Stack Overflow). Khi dùng HTTP/2, số lượng HTTP stream đồng thời tối đa sẽ được thương lượng giữa máy chủ và client (mặc định là 100).

Constructor

EventSource()

Tạo một EventSource mới để xử lý việc nhận server-sent events từ một URL được chỉ định, tùy chọn kèm chế độ thông tin xác thực.

Thuộc tính thể hiện

Giao diện này cũng kế thừa các thuộc tính từ lớp cha của nó, EventTarget.

EventSource.readyState Read only

Một số biểu thị trạng thái của kết nối. Các giá trị có thể là CONNECTING (0), OPEN (1), hoặc CLOSED (2).

EventSource.url Read only

Một chuỗi biểu thị URL của nguồn.

EventSource.withCredentials Read only

Một giá trị boolean cho biết đối tượng EventSource được khởi tạo với thông tin xác thực cross-origin (CORS) (true) hay không (false, mặc định).

Phương thức thể hiện

Giao diện này cũng kế thừa các phương thức từ lớp cha của nó, EventTarget.

EventSource.close()

Đóng kết nối, nếu có, và đặt thuộc tính readyState thành CLOSED. Nếu kết nối đã đóng, phương thức này không làm gì cả.

Sự kiện

error

Được kích hoạt khi kết nối tới nguồn sự kiện không mở được.

message

Được kích hoạt khi nhận dữ liệu từ nguồn sự kiện.

open

Được kích hoạt khi kết nối tới nguồn sự kiện đã mở.

Ngoài ra, chính nguồn sự kiện còn có thể gửi các thông điệp kèm trường event, điều này sẽ tạo ra các sự kiện động gắn với giá trị đó.

Ví dụ

Trong ví dụ cơ bản này, một EventSource được tạo để nhận các sự kiện không đặt tên từ máy chủ; một trang có tên sse.php chịu trách nhiệm tạo ra các sự kiện đó.

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);
};

Mỗi sự kiện nhận được sẽ khiến trình xử lý sự kiện onmessage của đối tượng EventSource chạy. Sau đó, nó tạo một phần tử <li> mới và ghi dữ liệu của thông điệp vào đó, rồi thêm phần tử mới vào danh sách đã có trong tài liệu.

Note: Bạn có thể tìm thấy một ví dụ đầy đủ trên GitHub, xem Simple SSE demo using PHP.

Để lắng nghe các sự kiện có tên, bạn cần một trình nghe cho mỗi kiểu sự kiện được gửi.

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);
});

Thông số kỹ thuật

Specification
HTML
# the-eventsource-interface

Tương thích trình duyệt

Xem thêm