---
concept: EventSource API
slug: eventsource-api
verified: true
verification_date: 2026-06-27
sources:
  - url: https://developer.mozilla.org/en-US/docs/Web/API/EventSource
    title: EventSource - Web API | MDN
    language: en
    date: 2026-03-16
    excerpt: "The EventSource interface is the web content's interface to server-sent events. It opens a persistent connection to an HTTP server, which then sends events in text/event-stream format."
  - url: https://developer.mozilla.org/ja/docs/Web/API/EventSource
    title: EventSource - Web API | MDN (Japanese)
    language: ja
    date: 2026-03-16
    excerpt: "HTTP サーバーとの間で永続的なコネクションを開き、イベントを text/event-stream の形式で受け取ります。"
  - url: https://segmentfault.com/a/1190000020628924
    title: content-type为text/event-stream的请求是什么？
    language: zh
    date: 2019-10-09
    excerpt: "EventSource.readyState代表连接状态，有以下三种情况：0—连接还未建立，1—连接已建立，2—连接已关闭"
related:
  - sse-protocol
tags:
  - api
  - javascript
  - browser
---

# EventSource API

## Definition
The `EventSource` interface is the browser-native API for consuming SSE streams. It handles connection management, automatic reconnection, and event parsing.

## Usage
```javascript
const source = new EventSource('/api/events');

source.onopen = () => console.log('connected');
source.onmessage = (event) => console.log(event.data);
source.onerror = () => console.log('error/reconnecting');

// Custom event types
source.addEventListener('update', (event) => {
  console.log(JSON.parse(event.data));
});

source.close(); // manually close
```

## Key Details
- Only supports GET requests (no custom headers — this is its biggest limitation)
- Cannot set Authorization headers — use cookie auth or URL token instead
- `readyState`: 0=CONNECTING, 1=OPEN, 2=CLOSED
- Automatic reconnection with exponential backoff (browser-managed)
- Runs in a Web Worker internally (non-blocking)
- Ignores lines starting with `:` (comments/heartbeats)

## Limitations vs fetch+ReadableStream
When you need custom headers (e.g., Authorization), use `fetch` + manual SSE parsing instead:
```javascript
const res = await fetch('/api/events', {
  headers: { Authorization: `Bearer ${token}` }
});
const reader = res.body.getReader();
// Parse SSE frames manually
```
This sacrifices automatic reconnection but gives full header control.

## Application in Blog Project
The blog's pixel-art client uses `fetch` + `ReadableStream.getReader()` instead of `EventSource` because it needs to POST with a body (EventSource only supports GET).
