Signatur
Beschreibung
Der Konstruktor EventSource() öffnet sofort eine HTTP-GET-Verbindung zur angegebenen URL. Über diese Verbindung schickt der Server Ereignisse im Format text/event-stream. Die Verbindung bleibt offen, und der Browser feuert für jede Nachricht ein message-Ereignis oder ein benanntes Ereignis, wenn der Server ein event:-Feld mitsendet.
Server-Sent Events (SSE) eignen sich für einseitige Echtzeit-Datenströme vom Server zum Client, zum Beispiel Live-Ticker, Benachrichtigungen, Fortschrittsanzeigen oder das Streamen von KI-Antworten. Anders als bei WebSockets läuft alles über normales HTTP. Proxys, Authentifizierung per Cookie und HTTP/2-Multiplexing funktionieren deshalb ohne Zusatzaufwand.
Bricht die Verbindung ab, verbindet sich der Browser automatisch neu. Dabei sendet er die zuletzt empfangene Ereignis-ID im Header Last-Event-ID mit, damit der Server an der richtigen Stelle weitermachen kann. Den Zustand der Verbindung zeigt readyState an: 0 (CONNECTING), 1 (OPEN) oder 2 (CLOSED). Mit close() beendest du die Verbindung endgültig.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $url Pflicht | string | URL | Adresse der Ressource, die den Ereignisstrom liefert. Relative URLs werden gegen die Basis-URL des Dokuments aufgelöst. | |
| $options | { withCredentials?: boolean } | { withCredentials: false } | Konfigurationsobjekt. withCredentials: true sendet bei Cross-Origin-Anfragen Cookies und HTTP-Authentifizierung mit (CORS-Modus include). |
Rückgabewert
EventSource-Instanz. Sie baut die Verbindung sofort auf und hat anfangs readyState === 0.Beispiele
Einfache Verbindung und Nachrichten empfangen
const quelle = new EventSource('/api/stream');
quelle.addEventListener('open', () => {
console.log('Verbunden, readyState:', quelle.readyState);
});
quelle.onmessage = (event) => {
console.log('Neue Nachricht:', event.data);
};
quelle.onerror = () => {
if (quelle.readyState === EventSource.CLOSED) {
console.log('Verbindung endgültig geschlossen');
} else {
console.log('Verbindung unterbrochen – Browser versucht Neuverbindung …');
}
};
Benannte Ereignisse mit JSON-Daten (Live-Kurse)
// Server sendet z. B.:
// event: kurs
// id: 42
// data: {"symbol":"DAX","wert":18450.3}
const kurse = new EventSource('/api/kurse');
kurse.addEventListener('kurs', (event) => {
const { symbol, wert } = JSON.parse(event.data);
console.log(`${symbol}: ${wert} (ID ${event.lastEventId})`);
});
// Verbindung beim Verlassen der Seite sauber beenden
window.addEventListener('pagehide', () => kurse.close());
Cross-Origin mit Cookies und Stream-Ende
const url = new URL('https://events.example.com/benachrichtigungen');
url.searchParams.set('kanal', 'team-7');
const sse = new EventSource(url, { withCredentials: true });
console.log(sse.withCredentials); // true
sse.addEventListener('fertig', () => {
// Server signalisiert das Ende – Neuverbindung verhindern
sse.close();
console.log('Stream beendet');
});
sse.onmessage = ({ data }) => console.log('Benachrichtigung:', data);
// Wichtig · Fallstricke
- Keine eigenen Header: Du kannst weder eigene HTTP-Header (etwa
Authorization) noch eine andere Methode als GET oder einen Anfragekörper setzen. Wenn du Tokens brauchst, nutze Cookies, einen Query-Parameter (Vorsicht: dieser landet in Logs) oderfetch()mit einemReadableStream. - Verbindungslimit: Über HTTP/1.1 erlauben Browser nur etwa 6 Verbindungen pro Domain, und zwar über alle Tabs hinweg. Mehrere offene EventSources können so andere Anfragen blockieren. HTTP/2 löst das Problem.
- Automatische Neuverbindung: Nach einem Fehler verbindet sich der Browser selbst neu. Den Abstand steuert der Server über das Feld
retry:(in Millisekunden). Antwortet der Server mit einem HTTP-Status ungleich 200 oder mit einem falschenContent-Type, schließt der Browser die Verbindung endgültig (readyState = 2). - Server-Anforderungen: Der Server muss mit
Content-Type: text/event-streamantworten und darf die Antwort nicht puffern. Bei nginx setzt du dafür z. B.X-Accel-Buffering: no. Kommentarzeilen (: ping) halten die Verbindung durch Proxys hindurch offen. - Sicherheit: Cross-Origin-Streams brauchen passende CORS-Header. Mit
withCredentialsmuss der Server zusätzlichAccess-Control-Allow-Credentials: trueund einen konkreten Origin (kein*) senden. Füge empfangene Daten niemals ungeprüft perinnerHTMLein, sonst droht XSS. - Fehler beim Erstellen: Ist die URL ungültig, wirft der Konstruktor einen
SyntaxError. Der Internet Explorer unterstützt EventSource nicht. Web Worker unterstützen es, Service Worker nicht.