JSON Toolkit

Adakah BOM merosakkan penghuraian JSON

Inti pati: BOM UTF-8 ialah tiga bait tidak kelihatan, jadi JSON.parse gagal pada aksara pertama dan melaporkan baris 1 lajur 1, yang membuatkan fail kelihatan kosong atau terpotong.

Pemula~4 min bacaanDiterbitkan 2026-10-30Dikemas kini 2026-10-30
Bagaimana BOM merosakkan penghuraian JSON dan bagaimana membuangnya

Pokoknya: semak tiga bait pertama untuk EF BB BF dan simpan semula sebagai UTF-8 tanpa BOM; di pelayan, buang U+FEFF di hadapan sebelum menghuraikan mana-mana fail yang dimuat naik atau pihak ketiga dan bukannya menyahpepijat kegagalan kemudian.

Ya — dan ia menghasilkan ralat penghuraian paling membingungkan daripada semua, kerana fail itu kelihatan sempurna.

Apa yang anda lihat

SyntaxError: Unexpected token  in JSON at position 0
Unexpected character '\uFEFF'

Aksara itu dalam mesej tidak kelihatan. Kedudukan 0 bermaksud bait yang paling awal.

cat tidak menunjukkan apa-apa yang luar biasa. hexdump -C file.json | head -1 menunjukkannya:

00000000  ef bb bf 7b 0a 20 20 22  61 22 3a 20 31 0a 7d 0a  |...{  "a": 1.}.|

7b ialah {. Tiga bait sebelum itu ialah BOM.

Dari mana BOM datang

Tanda urutan bait wujud untuk UTF-16, di mana urutan bait benar-benar berbeza-beza. UTF-8 mempunyai satu urutan bait, jadi BOM ialah overhed semata-mata — namun Notepad pada Windows, sesetengah eksport Excel, dan beberapa IDE lama masih menulisnya secara lalai.

RFC 8259 tidak samar-samar: JSON yang ditukar antara sistem mesti UTF-8, dan pelaksanaan tidak boleh menambah BOM. Penghurai boleh mengabaikan BOM di hadapan tetapi tidak diwajibkan. Pelayar dan Node memilih untuk tidak.

Tiga cara untuk membuangnya

Simpan tanpa BOM. Dalam VS Code, klik pengekodan pada bar status dan pilih "Save with Encoding → UTF-8", bukan "UTF-8 with BOM".

Buang daripada shell.

sed -i '1s/^\xEF\xBB\xBF//' data.json

Buang semasa membaca. Ini pembetulan yang tahan lama untuk apa-apa yang menerima fail yang dimuat naik atau pihak ketiga:

const text = require('node:fs').readFileSync('data.json', 'utf8').replace(/^\uFEFF/, '');
JSON.parse(text);

Dalam Python, open(path, encoding='utf-8-sig') mengendalikannya secara automatik.

Dua masalah yang kelihatan serupa

  • Ruang lebar sifar (U+200B) — terambil semasa menyalin JSON daripada halaman web; simptom sama, titik kod berbeza.
  • Petikan lebar penuh — IME Cina menukar "key" menjadi “key”, yang kelihatan hampir sama tetapi gagal sebagai Unexpected token “.

Ketiga-tiganya ialah bug aksara tidak kelihatan. Diagnostiknya sentiasa sama: buang bait pertama dalam hex dan bukannya merenung teks.

Soalan Lazim

Bagaimana saya boleh mengetahui sama ada fail bermula dengan BOM?

cat tidak menunjukkan apa-apa, jadi jalankan hexdump -C file.json | head -1. Jika output bermula dengan ef bb bf, fail mempunyai BOM; 7b (iaitu {) sepatutnya datang dahulu dalam fail UTF-8 yang bersih.

Mengapa ralat selalu menunjuk ke baris 1, lajur 1?

BOM terletak sebelum segala-galanya, jadi aksara pertama yang dibaca penghurai ialah U+FEFF. Kegagalan itu oleh itu berlaku pada permulaan fail, yang membuatkan fail kelihatan kosong.

Patutkah saya membuang BOM sebelum penghuraian?

Ya. Apabila pelayan membaca konfigurasi atau menghuraikan fail yang dimuat naik, buang U+FEFF di hadapan dahulu — replace(/^\uFEFF/, '') dalam Node, encoding='utf-8-sig' dalam Python — yang jauh lebih murah daripada mendiagnosisnya kemudian.

Bacaan lanjut