Back

Behebung von 'Unexpected token < in JSON at position 0'

Behebung von 'Unexpected token < in JSON at position 0'

Sie rufen response.json() auf und Ihre Anwendung stürzt mit SyntaxError: Unexpected token '<' in JSON at position 0 ab. Das <-Zeichen verrät Ihnen genau, was passiert ist: Ihr Code erwartete JSON, erhielt aber stattdessen HTML.

Dieser JSON-Parse-Fehler tritt ständig in modernen Frontend-Stacks auf – bei Browser-Fetch, Node.js, Next.js API-Routes und Serverless-Funktionen. Zu verstehen, warum er auftritt und wie Sie ihn schnell debuggen können, erspart Ihnen stundenlange Frustration.

Wichtigste Erkenntnisse

  • Der Fehler “Unexpected token <” bedeutet, dass Sie HTML als JSON parsen – das < stammt typischerweise von <!DOCTYPE html> oder einem HTML-Tag.
  • Häufige Ursachen sind falsche URLs, Authentifizierungs-Redirects, Server-Fehler, die HTML-Seiten zurückgeben, und fehlende Content-Type-Header.
  • Debuggen Sie, indem Sie zuerst den HTTP-Statuscode prüfen, dann den Content-Type-Header und schließlich den rohen Response-Body mit response.text().
  • Erstellen Sie defensive Fetch-Wrapper, die Responses vor dem Parsen validieren, um diese Probleme mit klaren Fehlermeldungen abzufangen.

Warum Ihre API HTML statt JSON zurückgibt

Der Fehler bedeutet, dass JSON.parse() auf ein HTML-Dokument gestoßen ist, wo es gültiges JSON erwartete. Das < an Position 0 ist typischerweise das öffnende Zeichen von <!DOCTYPE html> oder einem HTML-Tag.

Mehrere Szenarien verursachen diese Content-Type-Diskrepanz:

Falsche oder falsch geschriebene Endpoint-URLs. Ein Tippfehler in Ihrer Fetch-URL gibt eine 404-Seite zurück – die HTML ist, nicht JSON.

Authentifizierungs-Redirects. Abgelaufene Tokens oder fehlende Auth-Header lösen Weiterleitungen zu Login-Seiten aus. Ihr Fetch erhält das HTML der Login-Seite.

Server-Fehler, die HTML-Fehlerseiten zurückgeben. Ein 500-Fehler von Ihrem API-Gateway oder Cloud-Provider gibt oft eine gestylte HTML-Fehlerseite zurück statt einer JSON-Fehlerantwort.

Dev-Server, die Fallback-HTML für unbekannte Routen ausliefern. Viele SPAs geben das HTML-Grundgerüst für nicht übereinstimmende Pfade zurück, obwohl einige moderne Dev-Server strukturierte Fehler-Payloads zurückgeben.

Fehlende oder falsche Content-Type-Header. Server-Code, der vergisst, Content-Type: application/json zu setzen, verwendet möglicherweise standardmäßig HTML.

Ein praktischer Debugging-Ablauf für Fetch-API-Fehler

Wenn das JSON-Parsing fehlschlägt, folgen Sie dieser Sequenz, um die Grundursache zu identifizieren:

Schritt 1: Prüfen Sie den HTTP-Statuscode

Überprüfen Sie vor dem Parsen den Response-Status. Ein 4xx- oder 5xx-Status zeigt oft an, dass die Response kein JSON sein wird:

const response = await fetch('/api/data')

if (!response.ok) {
  console.error(`HTTP ${response.status}: ${response.statusText}`)
  const text = await response.text()
  console.error('Response body:', text.substring(0, 200))
  throw new Error(`Request failed with status ${response.status}`)
}

Schritt 2: Validieren Sie den Content-Type-Header

Prüfen Sie, was der Server vorgibt zu senden:

const contentType = response.headers.get('content-type')

if (!contentType || !contentType.includes('application/json')) {
  const text = await response.text()
  throw new Error(`Expected JSON, received: ${contentType}. Body: ${text.substring(0, 100)}`)
}

const data = await response.json()

Schritt 3: Loggen Sie den rohen Response-Body

Wenn das Parsen fehlschlägt, verwenden Sie response.text() statt response.json(), um zu sehen, was Sie tatsächlich erhalten haben:

async function fetchWithDebug(url) {
  const response = await fetch(url)
  const text = await response.text()
  
  try {
    return JSON.parse(text)
  } catch (error) {
    console.error('Failed to parse JSON. Raw response:', text.substring(0, 500))
    throw error
  }
}

Häufige Fallstricke in der Praxis

Falsche API-Basis-URLs in der Produktion. Umgebungsvariablen, die auf falsche Domains zeigen oder fehlende Trailing-Slashes haben, verursachen 404-Fehler, die HTML zurückgeben.

API-Gateways und CDNs, die Requests abfangen. Dienste wie Cloudflare, AWS API Gateway oder Vercel können ihre eigenen HTML-Fehlerseiten für Rate-Limits, Timeouts oder Fehlkonfigurationen zurückgeben.

Next.js App Router und Middleware-Redirects. Middleware oder Auth-Redirects geben oft HTML zurück, obwohl einige Redirect-Pfade stattdessen kleine JSON-Payloads ausgeben.

Server-Code ohne JSON-Header. Ihr API-Handler gibt Daten zurück, vergisst aber, den Response-Content-Type zu setzen:

// ❌ Fehlender Content-Type
res.send({ data: 'value' })

// ✅ Explizite JSON-Response
res.json({ data: 'value' })

CORS-Probleme. Browser blockieren fehlgeschlagene Preflight-Requests, bevor Ihr Code ausgeführt wird, aber falsch konfigurierte Server oder Proxies können trotzdem eine HTML-Fehlerseite zurückgeben, die Ihr Fetch-Aufruf erhält.

Defensives Fetch-Pattern

Umschließen Sie Ihre Fetch-Aufrufe mit Validierung, um diese Probleme frühzeitig abzufangen:

async function safeFetch(url, options = {}) {
  const response = await fetch(url, options)
  
  if (!response.ok) {
    const body = await response.text()
    throw new Error(`HTTP ${response.status}: ${body.substring(0, 100)}`)
  }
  
  const contentType = response.headers.get('content-type')
  if (!contentType?.includes('application/json')) {
    const body = await response.text()
    throw new Error(`Invalid content-type: ${contentType}`)
  }
  
  return response.json()
}

Fazit

Der Fehler “Unexpected token <” bedeutet immer, dass Sie HTML als JSON parsen. Debuggen Sie, indem Sie zuerst den Statuscode prüfen, dann den Content-Type-Header und schließlich den rohen Response-Body. Die meisten Fälle lassen sich auf falsche URLs, Auth-Redirects oder Server-Fehler zurückführen, die HTML-Seiten zurückgeben. Erstellen Sie defensive Fetch-Wrapper, die Responses vor dem Parsen validieren, um diese Probleme mit klaren Fehlermeldungen abzufangen.

Häufig gestellte Fragen (FAQs)

Produktionsumgebungen haben oft unterschiedliche Konfigurationen. Prüfen Sie, ob Ihre API-Basis-URL-Umgebungsvariable korrekt gesetzt ist, verifizieren Sie, dass Ihre Authentifizierungs-Tokens gültig sind, und bestätigen Sie, dass alle Proxies oder CDNs zwischen Ihrem Frontend und der API richtig konfiguriert sind. Produktionsserver können auch strengere CORS-Richtlinien haben, die dazu führen, dass Requests fehlschlagen.

Ja. Umschließen Sie Ihre Fetch-Aufrufe in einer defensiven Funktion, die den Response-Status und den Content-Type-Header prüft, bevor sie response.json() aufruft. Dies ermöglicht es Ihnen, den Fehler elegant zu behandeln und Benutzern eine aussagekräftige Nachricht anzuzeigen, anstatt abzustürzen. Validieren Sie Responses immer vor dem Parsen.

Verwenden Sie den Network-Tab Ihres Browsers, um die tatsächliche Response zu inspizieren. Wenn die Response HTML-Inhalt mit einem 404- oder 500-Status zeigt, gibt der Server eine Fehlerseite zurück. Wenn der Status 200 ist, aber der Inhalt HTML, prüfen Sie Ihren Server-Code, um sicherzustellen, dass er den korrekten Content-Type-Header setzt und JSON zurückgibt.

Die Methode response.json() versucht, den Response-Body als JSON zu parsen. Wenn der Body HTML oder anderen Nicht-JSON-Inhalt enthält, schlägt das Parsen fehl. Die Methode response.text() gibt einfach die rohe Response als String zurück, ohne zu parsen, weshalb sie unabhängig vom Content-Type funktioniert. Verwenden Sie text() zum Debuggen, um zu sehen, was Sie tatsächlich erhalten haben.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay