Rujukan Mesej Kesilapan JSON: Daripada Teks Kesilapan Terus kepada Pembetulan
Inti pati: Cari punca mengikut mesej JSON.parse yang tepat: 12 kesilapan kerap merentas Chrome, Firefox dan Safari, termasuk halaman kesilapan HTML, pemotongan dan penghuraian berganda.

Kesimpulan utama: apabila kesilapan JSON.parse muncul, ambil kedudukan dan token dahulu; kedudukan 0 bermaksud semak respons HTML, BOM, atau jenis yang salah, dan mesej "Expected" bermaksud lihat aksara sebelum itu — jangan baca semula baris demi baris daripada kedudukan yang dilaporkan.
Teks kesilapan bukan bunyi bising — ia adalah jawapan. Penghurai memberitahu anda aksara mana yang ditemuinya, apa yang dijangka, dan apa yang sebenarnya diterima. Mencari mengikut mesej kesilapan lebih baik daripada menulis semula seluruh dokumen dengan tangan.
Setiap kesilapan JSON.parse() mempunyai tiga bahagian: kedudukan (offset aksara, atau baris/lajur), jangkaan (Expected...), dan realiti (Unexpected token X, atau xxx is not valid JSON). Enjin menyusun kata-katanya secara berbeza — Chrome dan Node (V8) menyebut Expected ',' or '}' after property value in JSON at position 25, Firefox menyebut JSON.parse: expected ',' or '}' after property value in object at line 3 column 1, Safari menyebut JSON Parse error: Expected ',' or '}' — tetapi ketiga-tiganya menunjuk kepada kerosakan sintaks yang sama. Apabila anda merujuk kesilapan, abaikan susunan kata dan ambil tiga fakta: aksara mana, apa yang dijangka, apa yang tiba.
1. Jadual rujukan 12 kesilapan
Lajur kiri ialah serpihan paling mudah dikenal pasti daripada konsol anda (susunan kata V8). Varian Firefox/Safari dinyatakan dalam kurungan.
| Teks kesilapan (V8) | Punca sebenar | Pembetulan |
|---|---|---|
Unexpected token < in JSON at position 0 |
API memulangkan HTML (halaman 404, templat 500, pengalihan log masuk, sandaran proksi), bukan JSON | Semak response.status dan Content-Type dahulu; jangan betulkan JSON |
Unexpected end of JSON input |
Input kosong atau terpotong: badan kosong, 204, muat turun terganggu, salinan tertinggal baris terakhir | Kendalikan kes kosong, bandingkan Content-Length untuk mencari potongan |
Unexpected token o / "[object Object]" is not valid JSON |
Objek yang telah dihurai dihantar semula ke JSON.parse() dan dipaksa menjadi rentetan |
Semak typeof; jika ia objek, gunakannya terus |
"undefined" is not valid JSON |
Pemboleh ubah tidak pernah diberi nilai (JSON.parse(undefined)) |
Mulakan nilai sandaran; lindungi sebelum menghurai |
Expected double-quoted property name in JSON |
Koma hujung ({"a": 1,}); penghurai menjangka kunci lain dan menemui } |
Buang koma selepas item terakhir |
Expected property name or '}' in JSON |
Kunci tanpa petikan atau berpetikan tunggal ({name: "Ada"}, {'name': 'Ada'}) |
Letakkan tanda petikan berganda pada setiap kunci |
Expected ',' or '}' after property value in JSON |
Koma yang hilang ({"a": 1 "b": 2}) atau komen selepas nilai |
Tambah koma; buang komen |
Unexpected token '/' |
Komen // atau /* */ di dalam JSON |
Buangnya, atau hurai konfigurasi itu sebagai JSONC |
Bad control character in string literal |
Baris baharu mentah, tab, atau aksara kawalan U+0000–U+001F lain di dalam rentetan | Tulis \n; jana dengan JSON.stringify |
Unterminated string in JSON |
Rentetan dibuka dengan " dan tidak pernah ditutup, atau petikan dalaman tidak di-escape |
Escape petikan dalaman sebagai \" |
Unexpected non-whitespace character after JSON |
Dua dokumen dalam satu teks: {}{}, NDJSON, pembalut JSONP |
Pisahkan mengikut baris dan hurai setiap satu, atau gunakan penghurai NDJSON |
JSON.parse is not a function |
Pemboleh ubah anda sendiri menutupi JSON global |
Namakan semula pemboleh ubah itu; jangan sekali-kali menamakannya JSON |
Dua yang pertama wajar diteliti lebih dekat, kerana kedua-duanya tidak bermaksud "JSON anda salah" — ia bermaksud "apa yang anda terima bukan apa yang anda sangka".
2. Tiga punca lazim bagi kesilapan kedudukan 0
Kedudukan 0 bermaksud aksara pertama itu sendiri tidak sah. Jika tiada apa yang kelihatan mencurigakan, aksara itu mungkin tidak kelihatan. Tiga tersangka lazim:
Pertama: <, bermaksud HTML. Ini kesilapan hurai yang paling lazim dalam pengeluaran. URL yang salah, sesi tamat tempoh yang dialihkan oleh gateway, atau templat kesilapan pelayan — badan bermula dengan <!DOCTYPE html> dan penghurai berhenti pada aksara pertama. Langkah yang betul ialah membuka panel Network dan membaca respons mentah, kemudian membetulkan panggilan API, bukan JSON.
Kedua: BOM atau aksara lebar sifar. Fail yang disimpan oleh Notepad Windows sering bermula dengan BOM UTF-8 (\uFEFF), dan teks yang disalin daripada halaman web atau aplikasi sembang mungkin membawa ruang lebar sifar (\u200B–\u200D). Tidak kelihatan kepada anda, jelas kepada penghurai:
// Strip BOM and zero-width characters before parsing
const cleaned = raw.replace(/^\uFEFF/, '').replace(/[\u200B-\u200D]/g, '');
const data = JSON.parse(cleaned);
Ketiga: jenis yang salah. JSON.parse(undefined) melaporkan "undefined" is not valid JSON; JSON.parse(someObject) melaporkan Unexpected token o (objek itu dipaksa menjadi "[object Object]", dan o tidak sah pada kedudukan 1). Kedua-duanya bermaksud "data itu sudah dihurai" atau "tidak pernah ada data". Semak jenis, bukan sintaks:
let data = text;
if (typeof data === 'string') {
data = JSON.parse(data); // Parse only when it really is a string
}
3. Kedudukan menunjuk ke hiliran; punca berada di huluan
Dua kesilapan mengelirukan anda tentang lokasi, dan ia ialah dua entri yang paling kerap disalah baca dalam jadual:
- Koma yang hilang:
{"a": 1 "b": 2}melaporkanExpected ',' or '}' after property valuepada baris"b". Laporan itu betul, tetapi pembetulan terletak pada hujung baris sebelumnya. - Kurungan penutup yang hilang: sarang dalam yang tertinggal satu
}atau]membuat penghurai menelan segala-galanya hingga hujung input dan melaporkanUnexpected end of JSON input. Kedudukannya ialah hujung fail; jurang sebenar boleh jadi jauh lebih awal. Cari ke belakang untuk{atau[yang paling terkini tidak ditutup — mengira pasangan lebih baik daripada memerhati dengan mata.
Teknik umum ialah pembahagian dua: potong teks sebelum kedudukan yang dilaporkan dan hurai secara berasingan. Jika ia dihurai, masalahnya berhampiran kedudukan yang dilaporkan; jika tidak, bahagi dua lebih jauh ke belakang. Sempadan ketulan pertama yang gagal ialah tapak kesilapan sebenar. Bagi fail besar, formatkan dokumen itu dahulu — dengan inden sejajar, tahap yang hilang kelihatan secara sekilas pandang (pemformat JSON dalam talian sesuai untuk ini).
4. Empat keadaan "sihat palsu" yang dihurai dengan baik tetapi berkelakuan salah
Lebih teruk daripada kesilapan ialah tiada kesilapan tetapi data salah. Dalam keempat-empat kes, JSON itu sah dan penghurai gembira — masalahnya ialah bentuk data:
- Pengekodan berganda: seluruh dokumen telah di-
JSON.stringifydua kali, jadi penghuraian menghasilkan rentetan, bukan objek. Jikatypeof result === 'string', hurai semula — tetapi cari dan betulkan penyerialan berganda di puncanya. - Kunci pendua ditimpa secara senyap:
{"name": "Tom", "name": "Jerry"}ialah JSON yang sah, kebanyakan penghurai tidak merungut, dan nilai kedua menang. Ini menggigit apabila menggabungkan data daripada beberapa sumber; dedahkannya dengan pengesah JSON yang ketat sebelum ia menggigit anda. - NDJSON dianggap satu dokumen: API penstriman memancarkan satu objek setiap baris; penghuraian seluruh teks gagal dengan
Unexpected non-whitespace character after JSON. Pisahkan pada\ndan hurai setiap baris. - Kehilangan ketepatan nombor secara senyap: integer melebihi
2^53 - 1(ID snowflake) kembali dengan digit terakhir menjadi sifar, tanpa sebarang kesilapan. Hantar ID sebagai rentetan.
Benang yang menyatukan: penghurai percaya semuanya baik-baik sahaja. Jadi apabila data API kelihatan salah, cetak 80 aksara pertama teks mentah dan typeof-nya dahulu — sahkan bentuknya sebelum membincangkan kandungannya.
5. Jadikan kesilapan mustahil pada masa penulisan
Jadual rujukan ialah alat selepas fakta; pencegahan ialah alat sebelum fakta. Empat tabiat menghalang kebanyakan kesilapan sebelum ia berlaku:
// 1. Two checks before parsing any response
const response = await fetch('/api/users');
if (!response.ok) {
throw new Error(`HTTP ${response.status}: the API returned no data`);
}
const contentType = response.headers.get('content-type') ?? '';
if (!contentType.includes('application/json')) {
throw new Error(`Expected JSON, got ${contentType}`);
}
const data = await response.json(); // 2. json() already parses — do not parse again
- Serialkan untuk menjana, jangan sekali-kali gabungkan rentetan:
JSON.stringify()mengendalikan petikan, baris baharu, dan aksara kawalan dengan betul; rentetan yang dibina dengan tangan ialah punca utamaBad control characterdanUnterminated string. - Sentiasa tangkap: kesilapan
JSON.parseyang dilemparkan ialah ranap segerak kecuali ada sesuatu yang menangkapnya. Bagi input yang tidak dipercayai — localStorage, fail luaran — blok catch memerlukan nilai lalai atau pelaporan kesilapan eksplisit. - Serahkan struktur kepada Schema: sintaks yang sah tidak bermaksud struktur yang sah. Medan yang hilang dan jenis yang salah tergolong dalam pengesahan JSON Schema pada sempadan; lihat apa yang diselesaikan oleh JSON Schema.
6. Laluan keputusan pantas
Ringkaskan keseluruhan artikel menjadi satu urutan keputusan. Apabila anda melihat kesilapan, ambil kedudukan dan token dahulu:
- Kedudukan 0 → semak tiga punca:
<(HTML), BOM, jenis yang salah; end of input→ semak badan kosong atau terpotong, kemudian cari ke belakang untuk kurungan yang tidak ditutup;Expected ...→ lihat aksara sebelumnya; biasanya koma atau petikan yang hilang;after JSON data→ berbilang dokumen telah digabungkan; pisahkan mengikut baris;- Dihurai dengan baik tetapi data kelihatan salah → jalankan empat semakan "sihat palsu".
Digabungkan dengan triaj langkah demi langkah dalam cara membetulkan kesilapan hurai JSON, 90% masalah penghuraian selesai dalam masa lima minit. Simpan teks kesilapan itu sebagai penanda buku — ia ialah log penyahbugan yang ditulis oleh penghurai untuk anda, susunan katanya berubah sekali setiap tiga tahun, dan satu rujukan berbaloi untuk setahun.
Apakah maksud "Unexpected token in JSON"?
Penghurai menemui aksara yang tidak sah pada tempat itu dalam tatabahasa JSON. Token itu ialah aksara yang ditolak: < biasanya bermaksud API memulangkan HTML, ' bermaksud tanda petikan tunggal, / bermaksud komen, dan huruf biasa biasanya bermaksud kunci tanpa petikan atau literal khusus JavaScript seperti undefined atau NaN. Baca token dahulu, kemudian kedudukan, dan punca menyempit kepada satu.
Bagaimana saya membetulkan "Unexpected end of JSON input"?
Dua punca: input kosong (badan respons kosong, atau rentetan kosong dalam localStorage) atau input terpotong (muat turun terganggu, salinan tertinggal baris terakhir, had saiz). Kendalikan kes kosong dengan if (!text) return; kemudian sahkan kelengkapan dan tutup {, [, atau " yang paling terkini tidak ditutup. Perhatikan kesilapan itu juga boleh datang daripada kurungan dalam yang hilang — kedudukannya kebetulan berada di hujung fail.
Mengapa Chrome, Firefox, dan Safari melaporkan kesilapan secara berbeza?
Ketiga-tiga pelayar menghantar enjin JS yang berbeza (V8, SpiderMonkey, JavaScriptCore), dan masing-masing menyusun kata kesilapannya dengan caranya sendiri; MDN mendokumenkan semua varian rasmi. Tetapi ketiga-tiga kesilapan membawa tiga elemen yang sama — kedudukan, jangkaan, realiti — dengan semantik satu lawan satu. Terjemahkan kepada susunan kata V8 dan gunakan jadual ini sebagaimana adanya.
Kedudukan kesilapan menunjuk ke tempat yang kelihatan baik — apa seterusnya?
Kesilapan sebenar lebih awal. Kes lazim: koma yang hilang (dilaporkan pada baris seterusnya) dan kurungan penutup yang hilang (dilaporkan pada hujung fail). Berjalan ke belakang daripada kedudukan yang dilaporkan token demi token, atau bahagi dua: hurai separuh pertama secara berasingan, dan sempadan ketulan pertama yang gagal ialah tapak kesilapan sebenar.