JSON Toolkit

BOM ทำให้การ parse JSON พังไหม

สรุปสำคัญ: BOM แบบ UTF-8 คือสามไบต์ที่มองไม่เห็น ดังนั้น JSON.parse จึงล้มเหลวที่อักขระตัวแรกและรายงานบรรทัด 1 คอลัมน์ 1 ทำให้ไฟล์ดูเหมือนว่างหรือถูกตัดทอน

ผู้เริ่มต้นอ่านประมาณ 4 นาทีเผยแพร่ 2026-10-30อัปเดต 2026-10-30
BOM ทำให้การ parse JSON พังอย่างไรและวิธีลบมัน

สรุปสั้น ๆ: ตรวจสามไบต์แรกว่ามี EF BB BF หรือไม่ แล้วบันทึกใหม่เป็น UTF-8 ที่ไม่มี BOM; ฝั่งเซิร์ฟเวอร์ ให้ลบ U+FEFF ที่ต้นไฟล์ก่อน parse ไฟล์ที่อัปโหลดหรือไฟล์จากบุคคลที่สามทุกไฟล์ แทนที่จะไป debug ความล้มเหลวทีหลัง

ใช่ — และมันสร้าง error ตอน parse ที่สับสนที่สุดในบรรดา error ทั้งหมด เพราะไฟล์ดูปกติดีทุกอย่าง

สิ่งที่คุณเห็น

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

อักขระในข้อความนั้นมองไม่เห็น ตำแหน่ง 0 หมายถึงไบต์แรกสุด

cat ไม่แสดงอะไรแปลก ๆ แต่ hexdump -C file.json | head -1 แสดง:

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

7b คือ { สามไบต์ก่อนหน้ามันคือ BOM

BOM มาจากไหน

byte order mark เกิดมาเพื่อ UTF-16 ที่ลำดับไบต์แตกต่างกันจริง ๆ UTF-8 มีลำดับไบต์เดียว BOM จึงเป็น overhead ล้วน ๆ — แต่ Notepad บน Windows, การ export จาก Excel บางกรณี และ IDE เก่าบางตัวยังเขียนมันโดยค่าเริ่มต้น

RFC 8259 ชัดเจน: JSON ที่แลกเปลี่ยนระหว่างระบบต้องเป็น UTF-8 และ implementation ต้องไม่เพิ่ม BOM parser อาจ เพิกเฉย BOM ที่ต้นไฟล์ แต่ไม่จำเป็นต้องทำ เบราว์เซอร์และ Node เลือกที่จะไม่เพิกเฉย

สามวิธีกำจัดมัน

บันทึกโดยไม่มี BOM ใน VS Code ให้คลิกที่ encoding บน status bar แล้วเลือก "Save with Encoding → UTF-8" ไม่ใช่ "UTF-8 with BOM"

ลบจาก shell

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

ลบตอนอ่าน นี่คือวิธีแก้ที่ยั่งยืนสำหรับทุกอย่างที่รับไฟล์อัปโหลดหรือไฟล์จากบุคคลที่สาม:

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

ใน Python open(path, encoding='utf-8-sig') จัดการให้อัตโนมัติ

ปัญหาที่หน้าตาคล้ายกันอีกสองอย่าง

  • zero-width space (U+200B) — ติดมาเมื่อคัดลอก JSON จากหน้าเว็บ อาการเหมือนกันทุกอย่าง แต่ code point ต่างกัน
  • เครื่องหมายคำพูดแบบ full-width — IME ภาษาจีนเปลี่ยน "key" เป็น “key” ซึ่งดูแทบเหมือนกันแต่ล้มเหลวด้วย Unexpected token “

ทั้งสามเป็น bug ของอักขระที่มองไม่เห็น วิธีวินิจฉัยเหมือนกันเสมอ: dump ไบต์แรกออกมาเป็น hex แทนการจ้องข้อความเฉย ๆ

คำถามที่พบบ่อย

จะรู้ได้อย่างไรว่าไฟล์ขึ้นต้นด้วย BOM?

cat ไม่แสดงอะไร จึงต้องรัน hexdump -C file.json | head -1 ถ้า output ขึ้นต้นด้วย ef bb bf แสดงว่าไฟล์มี BOM; ในไฟล์ UTF-8 ที่สะอาด 7b (คือ {) ควรอยู่ตัวแรก

ทำไม error ถึงชี้บรรทัด 1 คอลัมน์ 1 เสมอ?

BOM อยู่ก่อนทุกอย่าง อักขระตัวแรกที่ parser อ่านจึงเป็น U+FEFF ความล้มเหลวจึงเกิดที่ต้นไฟล์ ทำให้ไฟล์ดูเหมือนว่าง

ควรลบ BOM ก่อน parse ไหม?

ควร เมื่อเซิร์ฟเวอร์อ่าน config หรือ parse ไฟล์ที่อัปโหลด ให้ลบ U+FEFF ที่ต้นไฟล์ก่อน — replace(/^\uFEFF/, '') ใน Node, encoding='utf-8-sig' ใน Python — ซึ่งถูกกว่าการวินิจฉัยทีหลังมาก

อ่านเพิ่มเติม