Start · Sprachen · JavaScript · Referenz · XMLHttpRequest.getAllResponseHeaders()

XMLHttpRequest.getAllResponseHeaders()

Methode

Gibt alle Antwort-Header einer <code>XMLHttpRequest</code>-Anfrage als einen String zurück, jede Zeile durch CRLF (<code>\r\n</code>) getrennt.

seit JavaScript Baseline: alle Browser Kategorie: webapi

Signatur

XMLHttpRequest.prototype.getAllResponseHeaders()

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

Typ
string
Beschreibung
Alle für das Skript sichtbaren Antwort-Header als CRLF-getrennter String. Wurde noch keine Antwort empfangen (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();
cache-control: no-cache content-length: 512 content-type: application/json; charset=utf-8 date: Mon, 06 May 2024 10:00:00 GMT

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();
application/json 42

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']);
200 application/json

// 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 gaben null zurück. Eine robuste Prüfung ist daher if (!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 über Access-Control-Expose-Headers ausdrücklich freigibt.
  • Set-Cookie und Set-Cookie2 fehlen 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 Aufteilen trim() auf, sonst entsteht ein leerer Eintrag.