Start · Sprachen · JavaScript · Referenz · XMLHttpRequest.timeout

XMLHttpRequest.timeout

Eigenschaft

Legt in Millisekunden fest, wie lange eine <code>XMLHttpRequest</code>-Anfrage maximal dauern darf, bevor sie automatisch abgebrochen wird. <code>0</code> bedeutet: kein Zeitlimit.

seit JavaScript Baseline: alle Browser (XMLHttpRequest Level 2) Kategorie: webapi

Signatur

XMLHttpRequest.timeout

Beschreibung

Die Eigenschaft timeout ist ein unsigned long und gibt an, wie viele Millisekunden eine Anfrage laufen darf. Ist diese Zeit abgelaufen, bevor die Antwort vollständig geladen wurde, bricht der Browser die Anfrage ab, setzt readyState auf 4 (DONE) und status auf 0 und löst das Ereignis timeout aus. Die Ereignisse load und error werden in diesem Fall nicht ausgelöst, loadend dagegen schon.

Der Standardwert ist 0, also kein Zeitlimit. Dann wartet die Anfrage so lange, bis der Server antwortet oder das Netzwerk bzw. der Browser die Verbindung trennt. In der Praxis sollte man deshalb ein sinnvolles Zeitlimit setzen, damit die Oberfläche bei langsamen oder hängenden Servern nicht endlos auf eine Antwort wartet.

Das Zeitlimit gilt für die gesamte Anfrage, von send() bis zum vollständigen Empfang der Antwort, also einschließlich Weiterleitungen und Download des Antwortinhalts. Man kann timeout auch noch nach dem Aufruf von send() ändern. Der neue Wert wird dann ab dem Start der Anfrage gerechnet, nicht ab dem Zeitpunkt der Änderung.

Parameter

Name Typ Default Beschreibung
$value number 0 Zeitlimit in Millisekunden (ganze Zahl ≥ 0). 0 schaltet das Zeitlimit ab.

Rückgabewert

Typ
number
Beschreibung
Das aktuell gesetzte Zeitlimit in Millisekunden. Ohne eigenen Wert ist es 0.

Beispiele

Einfaches Zeitlimit mit ontimeout

const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/benutzer');
xhr.timeout = 5000; // maximal 5 Sekunden

xhr.onload = () => {
  console.log('Status:', xhr.status);
};
xhr.ontimeout = () => {
  console.warn('Zeitüberschreitung nach', xhr.timeout, 'ms');
};
xhr.onerror = () => {
  console.error('Netzwerkfehler');
};

xhr.send();
Zeitüberschreitung nach 5000 ms (falls der Server nicht rechtzeitig antwortet)

XHR mit Zeitlimit als Promise für async/await

const request = (url, { timeout = 8000 } = {}) =>
  new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.responseType = 'json';
    xhr.timeout = timeout;

    xhr.addEventListener('load', () => {
      if (xhr.status >= 200 && xhr.status < 300) resolve(xhr.response);
      else reject(new Error(`HTTP ${xhr.status}`));
    });
    xhr.addEventListener('timeout', () =>
      reject(new Error(`Timeout nach ${timeout} ms`)));
    xhr.addEventListener('error', () =>
      reject(new Error('Netzwerkfehler')));

    xhr.send();
  });

const main = async () => {
  try {
    const daten = await request('/api/produkte', { timeout: 3000 });
    console.log('Produkte:', daten.length);
  } catch (err) {
    console.error(err.message);
  }
};
main();
Produkte: 42 // oder bei langsamer Antwort: Timeout nach 3000 ms

Wiederholung bei Zeitüberschreitung (Retry)

const ladeMitRetry = (url, versuche = 3) => {
  const xhr = new XMLHttpRequest();
  xhr.open('GET', url);
  xhr.timeout = 2000;

  xhr.ontimeout = () => {
    if (versuche > 1) {
      console.log(`Timeout – neuer Versuch (${versuche - 1} übrig)`);
      ladeMitRetry(url, versuche - 1);
    } else {
      console.error('Server antwortet nicht.');
    }
  };
  xhr.onload = () => console.log('Antwort erhalten:', xhr.status);
  xhr.send();
};

ladeMitRetry('/api/status');
Timeout – neuer Versuch (2 übrig) Antwort erhalten: 200

// Wichtig · Fallstricke

  • Synchrone Anfragen: Hat ein Fenster-Dokument die Anfrage mit open(method, url, false) synchron geöffnet, führt das Setzen von timeout zu einer InvalidAccessError-DOMException. In Web Workern ist die Kombination erlaubt. Synchrone XHR ist im Hauptthread ohnehin veraltet.
  • Status 0: Bei einer Zeitüberschreitung ist xhr.status gleich 0, wie bei Netzwerk- oder CORS-Fehlern. Zeitüberschreitungen erkennt man deshalb nur zuverlässig am timeout-Ereignis. Wer nur onerror behandelt, bekommt davon nichts mit.
  • Kein Ersatz für ein serverseitiges Zeitlimit: Die Anfrage wird nur im Client abgebrochen, der Server kann sie trotzdem weiterverarbeiten. Bei Anfragen, die Daten verändern (POST, PUT), sollten Wiederholungen deshalb idempotent sein.
  • Das Zeitlimit umfasst auch den Download. Bei großen Dateien und langsamen Verbindungen kann ein zu knappes Zeitlimit gültige Übertragungen abbrechen.
  • Moderne Alternative: fetch() zusammen mit AbortSignal.timeout(ms).
  • Kompatibilität: Wird von allen aktuellen Browsern unterstützt. Der Internet Explorer kannte die Eigenschaft ab Version 8, dort musste sie nach open() gesetzt werden. Setzt man sie immer nach open() und vor send(), ist man überall auf der sicheren Seite.