🌐 Detecting your location…

So beheben Sie das unerwartete SyntaxError-Token in JSON an Position 0

⏱️5 min read  ·  1,060 words

Der FehlerSyntaxError: Unerwartetes Token ‘<‘, “<!DOCTYPE”… ist kein gültiges JSON (oder „Unerwartetes Token in JSON an Position 0“) bedeutet, dass Sie versucht haben, etwas zu analysieren, das nicht JSON ist – normalerweise eine HTML-Fehlerseite oder eine leere Antwort. Hier erfahren Sie, wie Sie das Problem diagnostizieren und beheben können.

Was dieser Fehler bedeutet

Du hastJSON.parse() or response.json()angerufen auf eine Antwort, die kein gültiges JSON ist. Die Hinweise „Position 0“ und „<“ sind der Schlüssel: Position 0 bedeutet, dass das allererste Zeichen falsch ist, und „<“ bedeutet, dass die Antwort mit HTML beginnt (wie<!DOCTYPE html>) – Sie haben eine HTML-Fehlerseite anstelle von JSON erhalten.

Ursache 1: Der Server hat eine HTML-Fehlerseite

// 🐛 The API returned a 404/500 HTML page, not JSON
const response = await fetch('/api/data');
const data = await response.json();   // ❌ fails - response is HTML

// The response body is something like:
// 
404 Not Found...
// JSON.parse chokes on the '<' at position 0

// ✅ Check the response status and content type first
const response = await fetch('/api/data');
if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const contentType = response.headers.get('content-type');
if (!contentType?.includes('application/json')) {
  const text = await response.text();
  throw new Error(`Expected JSON but got: ${text.slice(0, 100)}`);
}
const data = await response.json();

zurückgegeben Ursache 2: Leerer Antworttext

// 🐛 Parsing an empty response (e.g., 204 No Content)
const data = await response.json();   // ❌ fails if body is empty

// ✅ Handle empty bodies
const text = await response.text();
const data = text ? JSON.parse(text) : null;

// ✅ Or check status
if (response.status === 204) {
  return null;   // No Content - nothing to parse
}
const data = await response.json();

Ursache 3: Falsche URL / falscher API-Endpunkt

// 🐛 Wrong URL returns your app's HTML (SPA fallback) instead of API JSON
fetch('/api/users')     // typo or wrong path
// If /api/users doesn't exist, the server may return index.html
// (common with SPAs) - which starts with '<' -> parse error

// ✅ Verify the URL is correct and the endpoint exists
// Check the Network tab to see what the response actually is
// Ensure API routes are registered and the path is exact

Ursache 4: Doppeltes Parsen von bereits geparstem JSON

// 🐛 The data is already an object, but you parse it again
const data = await response.json();   // already parsed to an object
const parsed = JSON.parse(data);      // ❌ parsing an object fails

// ✅ response.json() already parses - don't parse again
const data = await response.json();   // done - it's an object

// axios also auto-parses:
const { data } = await axios.get('/api');   // data is already parsed

Ursache 5: Nachgestellte Zeichen oder ungültiges JSON

// 🐛 The JSON has a syntax error (trailing comma, single quotes)
JSON.parse('{"name": "Alice",}');       // ❌ trailing comma
JSON.parse("{'name': 'Alice'}");        // ❌ single quotes not valid JSON
JSON.parse('{name: "Alice"}');          // ❌ unquoted key

// ✅ Valid JSON requires double quotes, no trailing commas
JSON.parse('{"name": "Alice"}');        // ✓ valid

Das robuste Abrufmuster

async function fetchJSON(url, options) {
  const response = await fetch(url, options);

  // Check status
  if (!response.ok) {
    const text = await response.text();
    throw new Error(`HTTP ${response.status}: ${text.slice(0, 200)}`);
  }

  // Handle empty responses
  const text = await response.text();
  if (!text) return null;

  // Parse safely with a helpful error
  try {
    return JSON.parse(text);
  } catch (err) {
    throw new Error(`Invalid JSON response: ${text.slice(0, 200)}`);
  }
}

// Usage
try {
  const data = await fetchJSON('/api/users');
} catch (err) {
  console.error('Fetch failed:', err.message);   // clear error, not cryptic
}

Debugging-Schritte

// 1. Log the raw response text to see what you actually got
const response = await fetch(url);
const text = await response.text();
console.log('Raw response:', text);   // reveals HTML, empty, or malformed JSON

// 2. Check the Network tab in DevTools
//    - Status code (200? 404? 500?)
//    - Content-Type header (application/json?)
//    - Response body (is it actually JSON?)

// 3. Test the endpoint directly
curl -i https://api.example.com/data
// See the exact status, headers, and body

Häufig gestellte Fragen

F: Warum wird im Fehler „<“ oder „<!DOCTYPE“ erwähnt?
A: Weil die Antwort mit HTML und nicht mit JSON beginnt. Sie haben eine HTML-Seite (normalerweise eine 404- oder 500-Fehlerseite oder die index.html Ihres SPA) anstelle des erwarteten JSON erhalten. Das „<“ ist das erste Zeichen des HTML-Tags, bei dem es sich nicht um gültiges JSON handelt.

F: Warum funktioniert es manchmal, bei anderen jedoch nicht?
A: Es schlägt fehl, wenn der Server Nicht-JSON zurückgibt – eine Fehlerseite (404/500), einen leeren Text oder eine Umleitung zu HTML. Es funktioniert, wenn die API den richtigen JSON zurückgibt. Der zeitweilige Fehler bedeutet oft, dass die API manchmal Fehler macht und HTML-Fehlerseiten zurückgibt.

F: Wie verhindere ich diesen Fehler?
A: Überprüfen Sie immerresponse.ok und den Inhaltstyp vor dem Aufruf vonresponse.json(), verarbeiten Sie leere Körper und schließen Sie das Parsen in try/catch ein. Verwenden Sie einen robusten Abruf-Wrapper (siehe oben), der eindeutige Fehler anstelle der kryptischen Meldung „Unerwartetes Token“ ausgibt.

F: Ich erhalte den HTML-Code meiner App anstelle von API-Daten. Warum?
A: Ihre API-URL ist wahrscheinlich falsch oder der Endpunkt existiert nicht, daher greift der Server auf die Bereitstellung der index.html Ihrer SPA zurück (die mit <!DOCTYPE beginnt). Stellen Sie sicher, dass der API-Pfad korrekt ist und der Endpunkt registriert ist. Überprüfen Sie die Registerkarte „Netzwerk“, um die tatsächliche Antwort anzuzeigen.

F: Sollte ich Response.json() oder Response.text() und dann JSON.parse() verwenden?
A: response.json() ist praktisch, löst aber bei ungültigem JSON einen kryptischen Fehler aus. Verwenden vonresponse.text() dannJSON.parse() In einem Try/Catch können Sie die Rohantwort überprüfen und eine klare Fehlermeldung ausgeben, wenn es sich nicht um JSON handelt – besser zum Debuggen.

Fazit

„SyntaxError: Unexpected token in JSON at position 0“ bedeutet, dass Sie versucht haben, Nicht-JSON zu analysieren – fast immer eine HTML-Fehlerseite (beginnt mit „<“) oder eine leere Antwort. Die Lösung:prüfenresponse.ok und den Inhaltstyp-Header vor dem Parsen, verarbeiten Sie leere Körper und schließen Sie JSON.parse in try/catchein . Der Hinweis „<“ sagt Ihnen, dass es sich bei der Antwort um HTML handelt. Untersuchen Sie also, warum – normalerweise eine falsche URL, ein Serverfehler, der eine HTML-Fehlerseite zurückgibt, oder ein SPA-Fallback. Verwenden Sie einen robusten Fetch-Wrapper, der die Rohantwort protokolliert und eindeutige Fehler ausgibt. Sobald Sie die Antwort überprüfen, bevor Sie sie analysieren, wird aus diesem kryptischen Fehler ein informativer Fehler, der Sie direkt auf das eigentliche Problem hinweist.

MD Rafikul Islam

Written by

MD Rafikul Islam is a software developer and the editor of TechPulse. He writes about developer tooling, hardware, and the practical decisions that come up in day-to-day engineering work — which laptop to buy, which framework to commit to, why a build broke at 2am. He tests the tools he writes about and says plainly when something is not worth the money. Corrections and corrections requests are welcome at rony.yf25@gmail.com.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা