Signatur
Beschreibung
Die Eigenschaft readyState zeigt an, in welcher Phase sich eine XMLHttpRequest-Anfrage gerade befindet. Sie ist schreibgeschützt und liefert einen der folgenden Zahlenwerte, für die es auch Konstanten am Konstruktor gibt:
- 0 –
UNSENT: Das Objekt wurde erstellt,open()aber noch nicht aufgerufen. - 1 –
OPENED:open()wurde aufgerufen. Jetzt können Header gesetzt undsend()aufgerufen werden. - 2 –
HEADERS_RECEIVED:send()wurde aufgerufen, Statuscode und Antwort-Header sind da. - 3 –
LOADING: Der Antwortkörper wird geladen.responseTextenthält bereits Teildaten. - 4 –
DONE: Der Vorgang ist abgeschlossen – erfolgreich, fehlgeschlagen oder abgebrochen.
Jede Änderung von readyState löst das Ereignis readystatechange aus. Früher war das der übliche Weg, um das Ende einer Anfrage zu erkennen: Man prüfte auf readyState === 4 und danach auf status. In neuem Code sind die Ereignisse load, error, progress und loadend meist übersichtlicher. Noch besser ist oft gleich die fetch()-API.
readyState ist trotzdem nützlich, wenn man älteren Code pflegt, Zwischenzustände auswerten will (z. B. Header schon bei Zustand 2 lesen) oder vor dem Aufruf von setRequestHeader() bzw. send() prüfen möchte, ob das Objekt im richtigen Zustand ist.
Rückgabewert
0 bis 4, die dem aktuellen Zustand entspricht (UNSENT, OPENED, HEADERS_RECEIVED, LOADING, DONE).Beispiele
Alle Zustandswechsel protokollieren
const xhr = new XMLHttpRequest();
console.log('Erstellt:', xhr.readyState);
xhr.onreadystatechange = () => {
console.log('readyState:', xhr.readyState);
};
xhr.open('GET', '/api/benutzer');
xhr.send();
Klassische Auswertung mit Konstanten statt Zahlen
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/produkte.json');
xhr.addEventListener('readystatechange', () => {
if (xhr.readyState !== XMLHttpRequest.DONE) return;
if (xhr.status >= 200 && xhr.status < 300) {
const produkte = JSON.parse(xhr.responseText);
console.log(`${produkte.length} Produkte geladen`);
} else {
console.error('Fehler:', xhr.status || 'Netzwerkfehler');
}
});
xhr.send();
Header schon bei HEADERS_RECEIVED auswerten und großen Download abbrechen
const xhr = new XMLHttpRequest();
xhr.open('GET', '/downloads/video.mp4');
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
const groesse = Number(xhr.getResponseHeader('Content-Length'));
if (groesse > 50 * 1024 * 1024) {
console.warn('Datei zu groß, Abbruch.');
xhr.abort(); // readyState wird danach 0
}
}
};
xhr.send();
XHR in ein Promise verpacken
const ladeText = (url) => new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
xhr.status === 200
? resolve(xhr.responseText)
: reject(new Error(`HTTP ${xhr.status}`));
}
};
xhr.send();
});
const text = await ladeText('/robots.txt');
console.log(text.split('\n')[0]);
// Wichtig · Fallstricke
DONEheißt nicht Erfolg: Zustand 4 wird auch bei Netzwerkfehlern, CORS-Blockaden, Timeouts undabort()erreicht. Prüfe immer zusätzlichstatus– bei Netzwerk- oder CORS-Fehlern ist er0.- Zustand 3 kann mehrfach auftreten: Manche Browser lösen
readystatechangewährend des Ladens wiederholt mitLOADINGaus. Code, der auf Zustand 3 reagiert, sollte das vertragen. - Nach
abort()gehtreadyStateauf0(UNSENT) zurück, nachdem zuvor kurzDONEgemeldet wurde. - Synchrone Anfragen (
open(..., false)) lösen die Zwischenzustände nicht zuverlässig aus und sind im Hauptthread veraltet, weil sie die Oberfläche blockieren. setRequestHeader()wirft einenInvalidStateError, wennreadyStatenichtOPENEDist.- Benannte Konstanten wie
XMLHttpRequest.DONEsind besser lesbar als „magische Zahlen“. Sehr alte Internet-Explorer-Versionen kannten die Konstanten nicht, das spielt heute aber keine Rolle mehr. Alle aktuellen Browser unterstützenreadyStatevollständig, auch in Web Workern.