Start · Sprachen · JavaScript · Referenz · new XMLHttpRequest()

new XMLHttpRequest()

Methode

Der Konstruktor <code>XMLHttpRequest()</code> erzeugt ein neues <code>XMLHttpRequest</code>-Objekt, über das HTTP-Anfragen an einen Server geschickt werden.

seit JavaScript Baseline: alle Browser (auch in Web Workern) Kategorie: webapi

Signatur

new XMLHttpRequest()

Beschreibung

Der Konstruktor new XMLHttpRequest() erzeugt ein neues, noch nicht konfiguriertes Anfrageobjekt. Sein readyState ist dann 0 (UNSENT). Erst mit open(method, url) legst du Methode und Ziel fest, danach kannst du Header setzen (setRequestHeader()) und die Anfrage mit send(body) abschicken.

XMLHttpRequest (XHR) ist die klassische Grundlage von AJAX. Trotz des Namens kann es beliebige Daten übertragen, also JSON, Text, Blob, ArrayBuffer, FormData oder ein Document. Welches Format die Antwort hat, bestimmst du über responseType.

Für neuen Code ist meist die Promise-basierte Fetch-API die bessere Wahl. XHR ist aber weiterhin sinnvoll, wenn du den Upload-Fortschritt über xhr.upload.onprogress brauchst, denn das kann fetch() bis heute nicht direkt. Außerdem begegnet dir XHR häufig in älterem Code und in Bibliotheken.

Jedes Objekt ist für genau eine Anfrage gedacht. Ein erneuter Aufruf von open() bricht eine laufende Anfrage ab. Für parallele Anfragen erzeugst du deshalb jeweils ein eigenes Objekt.

Rückgabewert

Typ
XMLHttpRequest
Beschreibung
Ein neues XMLHttpRequest-Objekt mit readyState === 0 (UNSENT).

Beispiele

JSON per GET laden

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1');
xhr.responseType = 'json';

xhr.addEventListener('load', () => {
  if (xhr.status >= 200 && xhr.status < 300) {
    console.log('Titel:', xhr.response.title);
  } else {
    console.error('HTTP-Fehler:', xhr.status);
  }
});

xhr.addEventListener('error', () => console.error('Netzwerkfehler'));
xhr.send();
Titel: delectus aut autem

XHR in ein Promise verpacken (mit Timeout)

const request = (method, url, body = null) =>
  new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.timeout = 5000; // 5 Sekunden
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.responseType = 'json';
    xhr.onload = () =>
      xhr.status < 400 ? resolve(xhr.response) : reject(new Error(`Status ${xhr.status}`));
    xhr.onerror = () => reject(new Error('Netzwerkfehler'));
    xhr.ontimeout = () => reject(new Error('Zeitüberschreitung'));
    xhr.send(body ? JSON.stringify(body) : null);
  });

const main = async () => {
  const post = await request('POST', 'https://jsonplaceholder.typicode.com/posts', { title: 'Hallo' });
  console.log('Neue ID:', post.id);
};
main();
Neue ID: 101

Datei-Upload mit Fortschrittsanzeige

// HTML: <input type="file" id="datei"> <progress id="balken" max="100" value="0"></progress>
const input = document.querySelector('#datei');
const balken = document.querySelector('#balken');

input.addEventListener('change', () => {
  const formData = new FormData();
  formData.append('upload', input.files[0]);

  const xhr = new XMLHttpRequest();
  xhr.upload.addEventListener('progress', (event) => {
    if (event.lengthComputable) {
      balken.value = Math.round((event.loaded / event.total) * 100);
    }
  });
  xhr.addEventListener('load', () => console.log('Upload fertig:', xhr.status));
  xhr.open('POST', '/api/upload');
  xhr.send(formData); // Content-Type setzt der Browser automatisch
});
Upload fertig: 200

// Wichtig · Fallstricke

  • Kein new, kein Objekt: Ruft man XMLHttpRequest() ohne new auf, wirft das einen TypeError.
  • HTTP-Fehler lösen kein error aus: Auch bei 404 oder 500 feuert load. Prüfe deshalb immer xhr.status. Das Ereignis error kommt nur bei Netzwerk- oder CORS-Fehlern.
  • Synchrone Anfragen vermeiden: open(method, url, false) blockiert den Hauptthread und gilt dort als veraltet. Browser geben dann Warnungen aus, außerdem funktionieren timeout und responseType in diesem Modus nicht.
  • Reihenfolge beachten: setRequestHeader() geht nur nach open() und vor send(), sonst gibt es einen InvalidStateError.
  • CORS: Anfragen an andere Ursprünge funktionieren nur, wenn der Server die passenden Access-Control-Allow-*-Header schickt. Cookies werden nur mit xhr.withCredentials = true mitgesendet.
  • Sicherheit: Füge Antwortdaten nie ungeprüft per innerHTML in die Seite ein, sonst droht XSS. Nutze stattdessen textContent oder bereinige die Daten vorher. Die Content Security Policy (connect-src) kann XHR-Ziele einschränken.
  • Kompatibilität: Wird von allen Browsern und in Web Workern unterstützt, aber nicht in Service Workern (dort nur fetch()). Node.js hat XHR nicht eingebaut.