Fetch/APIJavaScriptFetchAPIHTTP6 mnt baca

Mengatasi Unexpected token '<' is not valid JSON

fetch().json() meledak karena server mengembalikan HTML, bukan JSON. Cara mendiagnosis respons aslinya.

1 · Gejala & Log Pesan Error

error.log
Uncaught (in promise) SyntaxError: Unexpected token '<',
"<!DOCTYPE "... is not valid JSON
    at JSON.parse (<anonymous>)
    at Response.json (native)

// kadang tanpa pesan jelas, data tiba-tiba undefined

2 · Akar Penyebab Masalah

Kamu Meminta JSON, Server Memberi HTML

response.json() berasumsi body adalah JSON. Kalau server mengembalikan halaman HTML (diawali <!DOCTYPE), JSON.parse langsung menyerah di karakter < pertama.

Kenapa server memberi HTML padahal kamu memanggil API?

  1. URL salah / 404: endpoint tidak ada, server (atau SPA fallback) mengembalikan halaman 404 berformat HTML.
  2. Belum login / session habis: server me-redirect ke halaman login HTML.
  3. Server error 500: framework me-render halaman error HTML alih-alih JSON.
  4. Base URL salah: mis. fetch ke /api/users tapi proxy/dev-server tidak meneruskan, yang menjawab adalah halaman index.

Intinya: error JSON ini gejala, penyakitnya ada di respons HTTP-nya.

3 · Solusi & Diff Kode

✕ Sebelum (bermasalah)

before
// ❌ langsung .json() tanpa memeriksa respons
const res = await fetch("/api/users");
const data = await res.json(); // meledak kalau res adalah HTML
renderUsers(data);

✓ Sesudah (diperbaiki)

after
// ✔ periksa status & tipe konten dulu
const res = await fetch("/api/users");

if (!res.ok) {
  throw new Error("HTTP " + res.status + ": " + res.statusText);
}

const type = res.headers.get("content-type") ?? "";
if (!type.includes("application/json")) {
  const text = await res.text(); // baca sebagai teks untuk diagnosis
  console.error("Bukan JSON, dapat:", text.slice(0, 200));
  throw new Error("Server tidak mengembalikan JSON");
}

const data = await res.json();
renderUsers(data);

Langkah Perbaikan

  1. Buka tab Network di DevTools: klik request-nya, lihat tab Response/Preview. Di sanalah HTML aslinya terlihat: halaman 404? halaman login? halaman error Laravel?
  2. Cek status code: 404 berarti URL salah, 401/302 berarti masalah auth, 500 berarti bug di server.
  3. Perbaiki sumbernya: betulkan URL endpoint, pastikan login/session valid, atau perbaiki error 500 di backend.
  4. Pasang guard di kode seperti contoh di atas agar lain kali error-nya jelas ("Server tidak mengembalikan JSON") bukan SyntaxError yang membingungkan.
  5. Untuk API sendiri: pastikan route API selalu mengembalikan JSON bahkan saat error (di Laravel: pastikan request membawa header Accept: application/json).