Signatur
Beschreibung
Das load-Ereignis gehört zum Interface XMLHttpRequestEventTarget und tritt sowohl bei XMLHttpRequest-Objekten als auch bei deren upload-Objekt (XMLHttpRequestUpload) auf. Beim Anfrageobjekt bedeutet es: Die Antwort wurde vollständig empfangen. Beim upload-Objekt bedeutet es: Der Anfragekörper wurde vollständig an den Server übertragen.
Wichtig: „Erfolgreich“ bezieht sich nur auf die Übertragung, nicht auf den HTTP-Status. Auch Antworten mit 404 oder 500 lösen load aus. Netzwerkfehler, CORS-Blockaden, Abbrüche und Zeitüberschreitungen lösen stattdessen error, abort bzw. timeout aus. Deshalb sollte man im Handler immer xhr.status prüfen.
Das Ereignis ist ein ProgressEvent mit den Eigenschaften loaded, total und lengthComputable. Es wird nach readystatechange mit readyState === 4 und vor loadend ausgelöst. Es ist nicht abbrechbar (not cancelable) und steigt nicht auf (bubbelt nicht).
Registrieren lässt sich der Handler per addEventListener("load", handler) (mehrere Listener möglich, per removeEventListener entfernbar) oder über die Eigenschaft onload (nur ein Handler, wird bei erneuter Zuweisung überschrieben).
Rückgabewert
addEventListener noch die Zuweisung an onload liefern einen verwertbaren Rückgabewert. Der Handler erhält ein ProgressEvent.Beispiele
JSON laden mit addEventListener und Statusprüfung
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1');
xhr.responseType = 'json';
xhr.addEventListener('load', () => {
// load feuert auch bei 404/500 – daher Status prüfen
if (xhr.status >= 200 && xhr.status < 300) {
console.log('Titel:', xhr.response.title);
} else {
console.warn('HTTP-Fehler:', xhr.status);
}
});
xhr.addEventListener('error', () => console.error('Netzwerkfehler'));
xhr.send();
onload-Property und Listener wieder entfernen
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/status');
// Variante 1: onload (nur ein Handler möglich)
xhr.onload = (event) => {
console.log(`Geladen: ${event.loaded} Bytes, Status ${xhr.status}`);
};
// Variante 2: benannter Listener, der sich selbst wieder entfernt
const onLoad = () => {
console.log('Einmaliger Listener');
xhr.removeEventListener('load', onLoad);
};
xhr.addEventListener('load', onLoad);
xhr.send();
Upload-Fertigstellung über xhr.upload
const input = document.querySelector('input[type=file]');
input.addEventListener('change', () => {
const formData = new FormData();
formData.append('datei', input.files[0]);
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (e) => {
if (e.lengthComputable) {
console.log(`Upload: ${Math.round((e.loaded / e.total) * 100)} %`);
}
});
// Körper vollständig gesendet (Serverantwort steht noch aus)
xhr.upload.addEventListener('load', () => console.log('Upload übertragen'));
// Antwort vollständig empfangen
xhr.addEventListener('load', () => console.log('Server-Antwort:', xhr.status));
xhr.open('POST', '/upload');
xhr.send(formData);
});
XHR in ein Promise verpacken
const request = (method, url) => new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = () => (xhr.status >= 200 && xhr.status < 300)
? resolve(xhr.responseText)
: reject(new Error(`HTTP ${xhr.status}`));
xhr.onerror = () => reject(new Error('Netzwerkfehler'));
xhr.ontimeout = () => reject(new Error('Zeitüberschreitung'));
xhr.timeout = 5000;
xhr.send();
});
const main = async () => {
try {
const text = await request('GET', '/hallo.txt');
console.log(text);
} catch (err) {
console.error(err.message);
}
};
main();
// Wichtig · Fallstricke
- Kein HTTP-Erfolgsindikator:
loadwird auch bei Statuscodes wie404oder500ausgelöst. Immerxhr.statusprüfen. - CORS- und Netzwerkfehler lösen
errorstattloadaus; dabei istxhr.statusgleich0. Aufräumarbeiten, die in jedem Fall laufen sollen, gehören inloadend. - Upload-Listener vor
send()registrieren: Listener aufxhr.uploadmüssen vor dem Aufruf vonsend()gesetzt werden. Sie können außerdem einen CORS-Preflight erzwingen. - Reihenfolge:
readystatechange(readyState 4) →load→loadend. onloaderlaubt nur einen Handler; eine erneute Zuweisung überschreibt den vorherigen. Für mehrere HandleraddEventListenerverwenden.- Bei synchronen Anfragen (
open(..., false)) werden Ereignisse im Hauptthread blockierend verarbeitet; synchrones XHR ist veraltet und sollte gemieden werden. - Kompatibilität: In allen modernen Browsern und ab IE10 verfügbar. Für neuen Code ist die
fetch()-API meist die bessere Wahl; XHR bleibt aber nützlich, wenn man den Upload-Fortschritt verfolgen will.