Start · Sprachen · JavaScript · Referenz · XMLHttpRequest.withCredentials

XMLHttpRequest.withCredentials

Eigenschaft

Boolescher Wert, der festlegt, ob ein Cross-Origin-Request per <code>XMLHttpRequest</code> Anmeldeinformationen wie Cookies, HTTP-Authentifizierung oder TLS-Client-Zertifikate mitsendet.

seit JavaScript Baseline: alle Browser (XHR Level 2) Kategorie: webapi

Signatur

XMLHttpRequest.withCredentials

Beschreibung

Mit withCredentials steuerst du, ob ein XMLHttpRequest bei Cross-Origin-Anfragen (CORS) Anmeldeinformationen mitschickt. Dazu gehören Cookies, Authorization-Header aus der HTTP-Authentifizierung und TLS-Client-Zertifikate. Der Standardwert ist false: Ohne diese Einstellung sendet der Browser bei Anfragen an eine andere Origin keine Cookies. Außerdem werden Cookies aus der Antwort (Set-Cookie) dann ignoriert.

Bei Anfragen an die eigene Origin hat die Eigenschaft keine Wirkung. Dort werden Cookies immer mitgeschickt. Gebraucht wird withCredentials = true vor allem, wenn Frontend und API auf unterschiedlichen Domains, Subdomains oder Ports laufen, etwa app.example.com und api.example.com, und die Anmeldung über eine Session-Cookie läuft.

Damit der Browser die Antwort an das Skript weitergibt, muss der Server mitspielen: Er muss Access-Control-Allow-Credentials: true senden, und Access-Control-Allow-Origin muss die genaue Origin nennen. Der Platzhalter * ist in diesem Fall nicht erlaubt. Fehlt eine dieser Bedingungen, blockiert der Browser die Antwort, und im Skript löst der Request ein error-Event aus (status ist 0).

Setze die Eigenschaft nach open() und vor send(). Das Ändern während oder nach dem Senden wirft eine InvalidStateError-DOMException.

Parameter

Name Typ Default Beschreibung
$value boolean false true: Anmeldeinformationen werden bei Cross-Origin-Anfragen mitgesendet und Antwort-Cookies übernommen. false: Es werden keine Anmeldeinformationen gesendet.

Rückgabewert

Typ
boolean
Beschreibung
Die aktuelle Einstellung. Standard ist false.

Beispiele

Session-Cookie an eine API auf einer Subdomain mitsenden

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/user/me');
xhr.withCredentials = true; // Cookies von api.example.com mitschicken
xhr.responseType = 'json';

xhr.addEventListener('load', () => {
  if (xhr.status === 200) {
    console.log('Angemeldet als:', xhr.response.name);
  } else {
    console.log('Nicht angemeldet, Status:', xhr.status);
  }
});
xhr.addEventListener('error', () => {
  console.error('Netzwerk- oder CORS-Fehler');
});

xhr.send();
Angemeldet als: Anna

Wiederverwendbarer Promise-Wrapper mit optionalen Credentials

const request = (method, url, { body = null, credentials = false } = {}) =>
  new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open(method, url);
    xhr.withCredentials = credentials;
    xhr.setRequestHeader('Content-Type', 'application/json');
    xhr.onload = () =>
      xhr.status >= 200 && xhr.status < 300
        ? resolve(JSON.parse(xhr.responseText))
        : reject(new Error(`HTTP ${xhr.status}`));
    xhr.onerror = () => reject(new Error('CORS- oder Netzwerkfehler'));
    xhr.send(body ? JSON.stringify(body) : null);
  });

const main = async () => {
  const cart = await request('POST', 'https://shop-api.example.com/cart', {
    body: { productId: 42, qty: 1 },
    credentials: true
  });
  console.log('Artikel im Warenkorb:', cart.items.length);
};

main().catch(console.error);
Artikel im Warenkorb: 3

Passende Server-Antwort (Node.js/Express)

import express from 'express';

const app = express();

app.use((req, res, next) => {
  // Konkrete Origin statt '*' — Pflicht bei Credentials
  res.setHeader('Access-Control-Allow-Origin', 'https://app.example.com');
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
  res.setHeader('Vary', 'Origin');
  if (req.method === 'OPTIONS') return res.sendStatus(204);
  next();
});

app.get('/user/me', (req, res) => res.json({ name: 'Anna' }));
app.listen(3000, () => console.log('API läuft auf Port 3000'));
API läuft auf Port 3000

Zeitpunkt beachten: Setzen nach send() schlägt fehl

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data');
xhr.send();

try {
  xhr.withCredentials = true;
} catch (err) {
  console.log(err.name);
}
InvalidStateError

// Wichtig · Fallstricke

  • Wildcard verboten: Mit withCredentials = true darf der Server nicht Access-Control-Allow-Origin: * senden. Nötig sind die konkrete Origin und Access-Control-Allow-Credentials: true. Sonst blockiert der Browser die Antwort mit status 0 und ohne genaue Fehlermeldung im Skript. Die Ursache steht nur in der Konsole.
  • Drittanbieter-Cookies: Safari (ITP), Firefox (Total Cookie Protection) und Chrome können Cookies einer fremden Site trotz withCredentials blockieren. Session-Cookies für Cross-Site-Anfragen brauchen außerdem SameSite=None; Secure.
  • Sicherheit: Erlaube Credentials nur für eine feste Liste vertrauenswürdiger Origins. Wenn der Server den Origin-Header ungeprüft zurückspiegelt und gleichzeitig Credentials erlaubt, kann jede fremde Website im Namen eingeloggter Nutzer Daten lesen. Schreibende Endpunkte zusätzlich mit CSRF-Tokens absichern.
  • Zeitpunkt: Setzen nach send() wirft InvalidStateError. Synchrone Requests aus einem Fenster erlaubten die Eigenschaft in älteren Browsern ebenfalls nicht.
  • Same-Origin: Bei Anfragen an die eigene Origin ist die Eigenschaft wirkungslos.
  • Das Gegenstück in der Fetch-API ist credentials: 'include'. Der Standard von fetch ist 'same-origin'.
  • Kompatibilität: Wird von allen aktuellen Browsern unterstützt. Der alte IE nutzte stattdessen XDomainRequest, das keine Credentials kannte.