Signatur
Beschreibung
open() ist nach dem Erzeugen eines XMLHttpRequest-Objekts der erste Schritt jeder Anfrage. Die Methode legt die HTTP-Methode (z. B. GET, POST), die Ziel-URL und den Ausführungsmodus fest. Das Netzwerk wird dabei noch nicht angesprochen – die Anfrage geht erst mit send() raus.
Nach dem Aufruf wechselt readyState auf 1 (OPENED). Erst ab diesem Zustand dürfen Sie setRequestHeader() aufrufen oder Eigenschaften wie timeout und responseType sinnvoll setzen. Rufen Sie open() auf einem Objekt auf, das gerade eine Anfrage bearbeitet, wirkt das wie abort(): Die laufende Anfrage wird abgebrochen und das Objekt neu initialisiert.
Relative URLs werden gegen die Basis-URL des Dokuments aufgelöst. Die Methodennamen DELETE, GET, HEAD, OPTIONS, POST und PUT werden unabhängig von der Schreibweise in Großbuchstaben umgewandelt. Andere Methoden werden unverändert übernommen, deshalb sollte man PATCH immer groß schreiben.
In neuem Code ist meist die Fetch-API die bessere Wahl. XHR ist aber weiterhin nötig, wenn Sie den Upload-Fortschritt über xhr.upload.onprogress anzeigen wollen oder alten Code pflegen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $method Pflicht | string | HTTP-Methode, z. B. "GET", "POST", "PUT", "DELETE", "PATCH". CONNECT, TRACE und TRACK sind verboten und lösen einen SecurityError aus. |
|
| $url Pflicht | string | URL | Ziel-URL der Anfrage, absolut oder relativ zum Dokument. Objekte (z. B. URL) werden in einen String umgewandelt. |
|
| $async | boolean | true | Mit true läuft die Anfrage asynchron, das Ergebnis kommt über Events wie load. Mit false blockiert send(), bis die Antwort da ist (veraltet). |
| $user | string | null | null | Benutzername für die HTTP-Authentifizierung. |
| $password | string | null | null | Passwort für die HTTP-Authentifizierung. |
Rückgabewert
undefined). Als Nebeneffekt wechselt readyState auf 1 (OPENED), und das Event readystatechange wird ausgelöst.Beispiele
Einfacher asynchroner GET-Request mit JSON-Antwort
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'));
console.log('readyState nach open():', xhr.readyState);
xhr.send();
POST mit JSON-Body und eigenen Headern
const sendeKommentar = (daten) => new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/kommentare');
// setRequestHeader erst NACH open() erlaubt
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.timeout = 5000;
xhr.onload = () => (xhr.status === 201
? resolve(JSON.parse(xhr.responseText))
: reject(new Error(`Status ${xhr.status}`)));
xhr.onerror = () => reject(new Error('Netzwerkfehler'));
xhr.ontimeout = () => reject(new Error('Zeitüberschreitung'));
xhr.send(JSON.stringify(daten));
});
const neu = await sendeKommentar({ text: 'Toller Artikel!' });
console.log('Gespeichert mit ID', neu.id);
Datei-Upload mit Fortschrittsanzeige
const input = document.querySelector('#datei');
const balken = document.querySelector('progress');
input.addEventListener('change', () => {
const formData = new FormData();
formData.append('datei', input.files[0]);
const xhr = new XMLHttpRequest();
xhr.open('PUT', `/upload/${encodeURIComponent(input.files[0].name)}`);
xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
balken.value = Math.round((e.loaded / e.total) * 100);
}
});
xhr.addEventListener('load', () => console.log('Upload fertig:', xhr.status));
xhr.send(formData);
});
Objekt wiederverwenden – erneutes open() bricht ab
const xhr = new XMLHttpRequest();
xhr.addEventListener('abort', () => console.log('Vorherige Anfrage abgebrochen'));
const suche = (begriff) => {
// Erneutes open() bricht eine noch laufende Anfrage ab
xhr.open('GET', `/api/suche?q=${encodeURIComponent(begriff)}`);
xhr.send();
};
suche('jav');
suche('javascript'); // nur diese Anfrage wird zu Ende geführt
// Wichtig · Fallstricke
- Reihenfolge beachten:
setRequestHeader()voropen()wirft einenInvalidStateError.withCredentialsmuss vorsend()gesetzt sein. - Synchrone Anfragen (
async = false) blockieren den Hauptthread und gelten im Hauptthread als veraltet. Browser zeigen dafür Warnungen an. Außerhalb von Workern sindtimeoutund einresponseTypeungleich\"\"bei synchronen Anfragen nicht erlaubt und werfen einenInvalidAccessError. - Ausnahmen: Eine ungültige URL wirft
SyntaxError, eine ungültige Methode ebenfalls.CONNECT,TRACEundTRACKwerfenSecurityError. - Schreibweise der Methode:
'patch'wird nicht automatisch in Großbuchstaben umgewandelt. Viele Server lehnen es dann mit405ab. Schreiben Sie deshalb immer'PATCH'. - Sicherheit: Zugangsdaten über
user/passwordnur über HTTPS senden. Für Anfragen an andere Origins gilt CORS, der Server muss sie also ausdrücklich erlauben. Nutzereingaben in der URL immer mitencodeURIComponent()kodieren. - Kompatibilität: Wird von allen Browsern und in Web Workern unterstützt. In Service Workern und Node.js gibt es
XMLHttpRequestnicht, dort nutzen Siefetch().