Signatur
Beschreibung
Das timeout-Ereignis gehört zu XMLHttpRequestEventTarget und tritt auf, wenn eine Anfrage länger dauert als die in der Eigenschaft XMLHttpRequest.timeout (in Millisekunden) festgelegte Zeit. Der Browser bricht die Anfrage dann selbst ab. Der Handler erhält ein ProgressEvent.
Das Ereignis lässt sich auf zwei Wegen abonnieren: mit xhr.addEventListener("timeout", handler) oder über die Eigenschaft xhr.ontimeout = handler. Es gibt dasselbe Ereignis auch auf xhr.upload (einem XMLHttpRequestUpload-Objekt). Dort feuert es, wenn der Upload noch läuft, während die Zeit abläuft.
Die Reihenfolge der Ereignisse bei einer Zeitüberschreitung ist: readystatechange (mit readyState 4), dann timeout, dann loadend. Nicht ausgelöst werden load und error. Wenn du Zeitüberschreitungen gezielt behandeln willst, etwa um es erneut zu versuchen oder eine Meldung anzuzeigen, brauchst du also einen eigenen timeout-Handler.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses: "timeout" (nur bei addEventListener). |
|
| $handler Pflicht | (event: ProgressEvent) => void | Callback, der bei einer Zeitüberschreitung aufgerufen wird. Er erhält ein ProgressEvent mit loaded, total und lengthComputable. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie { once: true } oder signal zum späteren Entfernen. |
Rückgabewert
addEventListener gibt undefined zurück.Beispiele
Zeitüberschreitung mit addEventListener behandeln
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/langsame-antwort');
xhr.timeout = 3000; // 3 Sekunden
xhr.addEventListener('load', () => {
console.log('Antwort:', xhr.status);
});
xhr.addEventListener('timeout', (event) => {
console.warn(`Zeitüberschreitung nach ${xhr.timeout} ms – ${event.loaded} Bytes empfangen`);
});
xhr.send();
ontimeout-Eigenschaft und Handler wieder entfernen
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/status');
xhr.timeout = 2000;
const onTimeout = () => console.warn('Server antwortet nicht.');
// Variante 1: on-Property
xhr.ontimeout = onTimeout;
// Variante 2: Listener hinzufügen und später entfernen
xhr.addEventListener('timeout', onTimeout);
xhr.removeEventListener('timeout', onTimeout);
// on-Property wieder löschen
// xhr.ontimeout = null;
xhr.send();
Promise-Wrapper mit automatischem Neuversuch
const request = (url, { timeout = 2000, retries = 2 } = {}) =>
new Promise((resolve, reject) => {
const attempt = (left) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.timeout = timeout;
xhr.onload = () => resolve(xhr.responseText);
xhr.onerror = () => reject(new Error('Netzwerkfehler'));
xhr.ontimeout = () => {
if (left > 0) {
console.log(`Timeout – noch ${left} Versuch(e)`);
attempt(left - 1);
} else {
reject(new Error(`Timeout nach ${timeout} ms`));
}
};
xhr.send();
};
attempt(retries);
});
try {
const text = await request('/api/daten');
console.log(text);
} catch (err) {
console.error(err.message);
}
// Wichtig · Fallstricke
- Ohne
xhr.timeoutkein Ereignis: Der Standardwert ist0, also kein Zeitlimit. In diesem Fall feuerttimeoutnie. - Synchrone Anfragen: Setzt du
timeoutbei einer synchronen Anfrage (open(..., false)) in einem Dokument-Kontext, wirft der Browser eineInvalidAccessError-DOMException. In Workern ist das erlaubt. - Bei einer Zeitüberschreitung feuern weder
loadnocherror, wohl aberloadend. Wer Aufräumarbeiten nur imerror-Handler erledigt, verpasst diesen Fall. - Das Zeitlimit gilt für die gesamte Anfrage, gezählt ab
send(). Du kannstxhr.timeoutauch noch ändern, während die Anfrage läuft. Maßgeblich bleibt der Startzeitpunkt. xhr.upload.ontimeoutfeuert zusätzlich, wenn der Upload bei Ablauf der Zeit noch nicht abgeschlossen war.- Kompatibilität: Alle modernen Browser unterstützen das Ereignis. Im Internet Explorer ab Version 8 gab es
timeoutnur eingeschränkt. Für neuen Code empfiehlt sichfetch()mitAbortSignal.timeout().