Signatur
Beschreibung
Mit getAllResponseHeaders() liest du alle HTTP-Antwort-Header auf einmal aus, die das Skript sehen darf. Das Ergebnis ist ein einziger String. Jeder Header steht in einer eigenen Zeile im Format name: wert, die Zeilen sind durch \r\n getrennt. Die Methode ist nützlich zum Debuggen, zum Protokollieren und immer dann, wenn du vorher nicht weißt, welche Header der Server schickt, zum Beispiel eigene X-*-Header oder Header für die Seitenaufteilung (Pagination).
Header stehen bereit, sobald readyState den Wert HEADERS_RECEIVED (2) erreicht hat. Die Methode kann also schon vor dem vollständigen Laden des Antwort-Bodys aufgerufen werden, etwa im readystatechange-Handler. Moderne Browser liefern die Header-Namen kleingeschrieben und sortiert. Kommt derselbe Header mehrfach vor, werden seine Werte mit ", " zu einem Eintrag zusammengefasst.
Wenn du nur einen bestimmten Header brauchst, nimm besser getResponseHeader(name). Soll die Header-Liste als Objekt oder Map vorliegen, musst du den String selbst aufteilen (siehe Beispiele). In neuem Code ist die fetch()-API mit ihrem Headers-Objekt meist die bequemere Wahl.
Rückgabewert
readyState kleiner als 2) oder ist ein Netzwerkfehler aufgetreten, ist das Ergebnis ein leerer String "". Ältere Spezifikationen und Browser gaben in diesem Fall null zurück.Beispiele
Alle Header nach dem Laden ausgeben
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/users');
xhr.addEventListener('load', () => {
console.log(xhr.getAllResponseHeaders());
});
xhr.send();
Header-String in eine Map umwandeln
const parseHeaders = (raw) => {
const headers = new Map();
raw.trim().split(/[\r\n]+/).forEach((line) => {
const index = line.indexOf(': ');
if (index === -1) return;
const name = line.slice(0, index).toLowerCase();
const value = line.slice(index + 2);
headers.set(name, value);
});
return headers;
};
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/articles?page=2');
xhr.onreadystatechange = () => {
// Header sind schon ab HEADERS_RECEIVED verfügbar
if (xhr.readyState === XMLHttpRequest.HEADERS_RECEIVED) {
const headers = parseHeaders(xhr.getAllResponseHeaders());
console.log(headers.get('content-type'));
console.log(headers.get('x-total-count'));
}
};
xhr.send();
Als Promise verpacken und Header als Objekt zurückgeben
const requestWithHeaders = (url) =>
new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = () => {
const headers = Object.fromEntries(
xhr.getAllResponseHeaders()
.trim()
.split('\r\n')
.filter(Boolean)
.map((line) => {
const i = line.indexOf(':');
return [line.slice(0, i).trim().toLowerCase(), line.slice(i + 1).trim()];
})
);
resolve({ status: xhr.status, headers, body: xhr.responseText });
};
xhr.onerror = () => reject(new Error('Netzwerkfehler'));
xhr.send();
});
const { status, headers } = await requestWithHeaders('/api/status');
console.log(status, headers['content-type']);
// Wichtig · Fallstricke
- Leerer String statt
null: Nach der aktuellen Spezifikation (WHATWG XHR) liefern alle modernen Browser"", wenn noch keine Header empfangen wurden. Sehr alte Browser gabennullzurück. Eine robuste Prüfung ist daherif (!raw). - CORS schränkt die Liste ein: Bei Anfragen an einen anderen Ursprung (Cross-Origin) siehst du nur die CORS-freigegebenen Header (
Cache-Control,Content-Language,Content-Length,Content-Type,Expires,Last-Modified,Pragma) sowie Header, die der Server überAccess-Control-Expose-Headersausdrücklich freigibt. Set-CookieundSet-Cookie2fehlen immer, auch bei Anfragen an denselben Ursprung.- Header-Namen sind in modernen Browsern kleingeschrieben. Normalisiere trotzdem mit
toLowerCase(), wenn du sie vergleichst, denn HTTP-Header-Namen unterscheiden keine Groß- und Kleinschreibung. - Mehrfach gesendete Header werden mit
", "zusammengefasst. Bei Werten, die selbst Kommas enthalten, lassen sie sich deshalb nicht immer eindeutig wieder trennen. - Die letzte Zeile endet ebenfalls mit
\r\n. Rufe vor dem Aufteilentrim()auf, sonst entsteht ein leerer Eintrag.