JSON Toolkit

BOM이 JSON 파싱을 깨나

핵심 요약: UTF-8 BOM은 보이지 않는 세 바이트라 `JSON.parse`가 첫 문자에서 실패하고 1행 1열을 보고해 파일이 비어 있거나 잘린 것처럼 보입니다.

초급약 4분 소요2026-10-30 발행2026-10-30 업데이트
BOM이 JSON 파싱을 깨는 방식과 제거법

핵심부터 말하면, 앞 세 바이트가 EF BB BF인지 확인하고 BOM 없는 UTF-8로 다시 저장하세요. 서버에서는 업로드나 서드파티 파일을 파싱하기 전에 앞의 U+FEFF를 제거해 나중에 실패를 디버그하지 마세요.

예, 그리고 모든 파싱 오류 중 가장 혼란스러운 것을 냅니다. 파일이 완벽해 보이기 때문입니다.

보이는 것

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은 어디서 오나

바이트 순서 표시는 UTF-16을 위해 존재했고, 실제로 바이트 순서가 달랐습니다. UTF-8은 바이트 순서가 하나라 BOM은 순수 오버헤드입니다. 그러나 Windows 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')가 자동으로 처리합니다.

닮은 문제 둘

  • 폭 0 공백(U+200B) — 웹 페이지에서 JSON을 복사할 때 들어가며, 증상은 같고 코드 포인트가 다릅니다.
  • 전각 인용부호 — 중국어 IME가 "key"를 “key”로 바꾸고, 거의 동일해 보이지만 Unexpected token “로 실패합니다.

셋 다 보이지 않는 문자 버그입니다. 진단은 항상 같습니다. 텍스트를 들여다보지 말고 앞 바이트를 hex로 덤프하세요.

FAQ

파일이 BOM으로 시작하는지 어떻게 확인하나?

cat은 아무것도 보여 주지 않으므로 hexdump -C file.json | head -1을 실행하세요. 출력이 ef bb bf로 시작하면 BOM이 있고, 깨끗한 UTF-8 파일에서는 7b({)가 먼저 와야 합니다.

오류가 왜 항상 1행 1열을 가리키나?

BOM이 모든 것 앞에 있어 파서가 읽는 첫 문자가 U+FEFF입니다. 그래서 실패가 파일 시작에 떨어져 파일이 비어 보입니다.

파싱 전에 BOM을 제거해야 하나?

예. 서버가 설정을 읽거나 업로드 파일을 파싱할 때 먼저 앞의 U+FEFF를 제거하세요. Node에서는 replace(/^\uFEFF/, ''), Python에서는 encoding='utf-8-sig'이며, 나중에 진단하는 것보다 훨씬 저렴합니다.

더 읽을거리