📚 EVEDAYS Guide Book
[개발자 도구]•6분 소요

JSON 파싱 오류가 나는 다섯 가지 이유와 큰 숫자 정밀도 함정

1. JSON은 생각보다 엄격합니다


JSON은 자바스크립트 객체 리터럴과 비슷해 보이지만 훨씬 좁은 문법입니다. RFC 8259와 ECMA-404가 정의하며, 자바스크립트에서 되는 것이 JSON에서는 안 되는 경우가 많습니다.

2. 파싱이 실패하는 다섯 가지 원인


① 마지막 쉼표 (trailing comma)
{"a": 1, "b": 2,} — 마지막 항목 뒤 쉼표는 오류입니다. 자바스크립트에서는 허용되지만 JSON에서는 안 됩니다.

② 키에 큰따옴표가 없음
{a: 1} — 키는 반드시 큰따옴표로 감싼 문자열이어야 합니다.

③ 작은따옴표 사용
{'a': 'b'} — JSON은 큰따옴표만 인정합니다.

④ 주석
// 설명 이나 /* */ 는 JSON 표준에 없습니다. 설정 파일에서 주석을 쓰려면 JSONC나 JSON5 같은 확장 형식이 필요합니다.

⑤ 특수값
NaN, Infinity, undefined는 JSON에 없습니다. 숫자가 아닌 상태는 null로 표현하거나 문자열로 감싸야 합니다.

이 외에 문자열 안의 줄바꿈을 그대로 넣는 것도 오류입니다. \n으로 이스케이프해야 합니다.

3. 오류 위치를 읽는 법


파서는 대개 "position 42" 같은 위치를 알려줍니다. 그런데 실제 원인은 그보다 앞에 있는 경우가 많습니다. 따옴표를 하나 빠뜨리면 파서는 뒤쪽 문자열까지 값의 일부로 삼다가 한참 뒤에서야 실패합니다.

포매터에 넣어 구조를 펼쳐보면 어디서 중첩이 어긋났는지 눈으로 찾기 쉬워집니다.

4. 큰 숫자 정밀도 함정


이건 문법 오류가 아니라 조용히 값이 바뀌는 문제라 더 위험합니다.

자바스크립트의 숫자는 배정밀도 부동소수점이라 안전하게 표현 가능한 정수 범위가 다음까지입니다.

Number.MAX_SAFE_INTEGER = 9007199254740991 (약 9007조)

이보다 큰 정수를 JSON.parse로 읽으면 값이 조용히 변합니다. 예를 들어 12345678901234567890은 파싱 후 12345678901234567000 이 됩니다. 오류도 경고도 없습니다.

언제 문제가 되는가
  • 스노우플레이크 방식의 64비트 ID (트위터, 디스코드 등)

  • 데이터베이스의 BIGINT 기본키

  • 원 단위 없이 표현한 큰 금액


  • 대응
    서버가 이런 값을 보낼 때는 문자열로 직렬화하는 것이 표준적인 해법입니다. {"id": "12345678901234567890"} 처럼요. 클라이언트에서 반드시 숫자로 다뤄야 한다면 BigInt와 커스텀 리바이버를 씁니다.

    5. JSON의 변형들


    | 형식 | 차이 | 쓰임 |
    |---|---|---|
    | JSON | 표준 | API 응답, 데이터 교환 |
    | JSONC | 주석 허용 | VS Code 설정 등 |
    | JSON5 | 주석, 후행 쉼표, 작은따옴표 허용 | 사람이 직접 쓰는 설정 파일 |
    | NDJSON / JSON Lines | 한 줄에 JSON 하나 | 로그, 스트리밍, 대용량 처리 |

    설정 파일이라고 해서 JSONC를 API 응답에 쓰면 안 됩니다. 표준 파서가 거부합니다.

    6. 보안 주의


    JSON 문자열을 eval()로 처리하는 코드를 아직 볼 수 있습니다. 절대 쓰지 마세요. 신뢰할 수 없는 입력에 코드가 들어 있으면 그대로 실행됩니다. JSON.parse는 안전합니다.

    7. 도구


    EVEDAYS JSON 포매터는 문법 검증과 정렬을 브라우저 안에서 처리합니다. API 응답에 개인정보나 토큰이 들어 있는 경우가 많으므로, 외부 서버로 전송하지 않는 도구를 쓰는 편이 안전합니다.

    8. 출처


  • RFC 8259 — The JavaScript Object Notation (JSON) Data Interchange Format

  • ECMA-404 — The JSON Data Interchange Syntax

  • MDN — JSON.parse()
  • EVEDAYS Editorial Team