آیا BOM تجزیه JSON را میشکند
جمعبندی: BOM در UTF-8 سه بایت نامرئی است، پس JSON.parse روی نخستین نویسه شکست میخورد و خط ۱ ستون ۱ را گزارش میکند، که فایل را خالی یا ناقص نشان میدهد.

جمعبندی: سه بایت اول را برای EF BB BF بررسی کنید و بهصورت UTF-8 بدون BOM دوباره ذخیره کنید؛ در سرور، پیش از تجزیه هر فایل آپلودی یا شخص ثالث، U+FEFF ابتدایی را حذف کنید نه اینکه بعداً خطا را عیبیابی کنید.
بله — و گیجکنندهترین خطای تجزیه از همه را تولید میکند، چون فایل کاملاً سالم به نظر میرسد.
چه میبینید
SyntaxError: Unexpected token in JSON at position 0
Unexpected character '\uFEFF'
آن نویسه در پیام نامرئی است. موقعیت ۰ یعنی همان نخستین بایت.
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 از کجا میآید
نشانه ترتیب بایت برای UTF-16 وجود داشت که ترتیب بایت واقعاً متغیر بود. UTF-8 یک ترتیب بایت واحد دارد، پس BOM سربار محض است — اما Notepad ویندوز، برخی خروجیهای Excel و چند IDE قدیمیتر همچنان بهصورت پیشفرض مینویسندش.
RFC 8259 روشن است: JSON مبادلهشده بین سیستمها باید UTF-8 باشد و پیادهسازیها نباید BOM اضافه کنند. پارسرها میتوانند BOM ابتدایی را نادیده بگیرند اما الزامی نیست. مرورگرها و Node انتخاب میکنند نادیده نگیرند.
سه راه برای خلاص شدن از آن
بدون BOM ذخیره کنید. در VS Code، روی رمزگذاری در نوار وضعیت کلیک کنید و «Save with Encoding → UTF-8» را انتخاب کنید، نه «UTF-8 with BOM».
از شل حذفش کنید.
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') خودکار مدیریتش میکند.
دو مشکل شبیه
- فاصله با عرض صفر (U+200B) — هنگام کپی JSON از صفحه وب گرفته میشود؛ نشانه یکسان، نقطه کد متفاوت.
- گیومه تمامعرض — یک IME چینی
"key"را به“key”تبدیل میکند که تقریباً یکسان به نظر میرسد اما بهصورتUnexpected token “شکست میخورد.
هر سه باگ نویسه نامرئی هستند. تشخیص همیشه یکسان است: نخستین بایتها را به هگز دامپ کنید نه اینکه به متن زل بزنید.
پرسشهای متداول
چگونه بفهمم فایل با BOM شروع میشود؟
cat چیزی نشان نمیدهد، پس hexdump -C file.json | head -1 اجرا کنید. اگر خروجی با ef bb bf شروع شود، فایل BOM دارد؛ در یک فایل UTF-8 تمیز باید 7b (همان {) اول بیاید.
چرا خطا همیشه به خط ۱، ستون ۱ اشاره میکند؟
BOM پیش از همهچیز مینشیند، پس نخستین نویسهای که پارسر میخواند U+FEFF است. شکست بنابراین در ابتدای فایل رخ میدهد، که فایل را خالی نشان میدهد.
آیا باید پیش از تجزیه BOM را حذف کنم؟
بله. وقتی سرور پیکربندی میخواند یا فایل آپلودی را تجزیه میکند، اول U+FEFF ابتدایی را حذف کنید — replace(/^\uFEFF/, '') در Node، encoding='utf-8-sig' در Python — که بسیار ارزانتر از عیبیابی بعدی است.