본문으로 건너뛰기
jsonbeautifiers
한국어

JSON 검증기

모든 오류의 정확한 행, 열, 원인, 해결 방법을 보여 줍니다.

입력

붙여 넣은 것은 여러분의 브라우저를 떠나지 않습니다. connect-src 허용 목록 덕분에 이는 약속이 아니라 브라우저가 강제하는 보장입니다. 직접 확인하기

검증이 답하는 질문은 하나입니다. 이것이 올바른 JSON 문서인가? 쓸모 있는 부분은 답이 "아니오"일 때 벌어지는 일입니다. 대부분의 검증기는 예기치 않은 토큰이 있다고만 말하고 찾는 일은 여러분에게 넘깁니다. 이 도구는 어떤 문자가, 몇 번째 행과 열에서, 대신 무엇을 기대했는지, 그리고 어떻게 고치면 되는지까지 알려 줍니다.

첫 번째 문제에서 멈추지도 않습니다. 네 군데가 잘못된 문서는 네 건으로 보고되므로, 네 번이 아니라 한 번에 고칠 수 있습니다.

무엇을 검사하는가

RFC 8259의 문법 전체입니다. 사람들이 의외라고 여기는 부분까지 포함해서요.

공백
토큰 사이에 올 수 있는 문자는 공백, 탭, 캐리지 리턴, 라인 피드 네 가지뿐입니다. 줄바꿈 없는 공백, 폭이 0인 공백, 전각 공백은 모두 문법 오류이고, 이 검증기는 예기치 않은 토큰이라고 하는 대신 그 문자의 이름을 알려 줍니다. 웹 페이지, PDF, 채팅 클라이언트에서 JSON을 복사할 때 끊임없이 딸려 옵니다.
숫자
앞자리 0, 앞의 플러스 기호, 16진수, 끝에 남은 소수점, NaN, Infinity 모두 안 됩니다. 원인도 해결책도 다르기 때문에 위반마다 따로 메시지를 냅니다.
문자열
허용되는 이스케이프 시퀀스는 아홉 가지뿐입니다. U+0020 미만의 제어 문자는 반드시 이스케이프해야 합니다. 짝 없는 서로게이트는 경고로 표시합니다. 파싱은 되지만 UTF-8로 다시 인코딩하면 살아남지 못하기 때문입니다.
최상위 값은 하나
한 문서는 정확히 하나를 담습니다. 한 줄에 하나씩 값이 여러 개 있는 것은 NDJSON이고, 이 검증기는 그 형태를 알아보고 일반적인 "뒤에 내용이 더 있음" 오류 대신 그렇게 알려 줍니다.

오류가 아닌 경고

파싱은 되는데도 오후를 망치는 것들이 있습니다. 출력을 막지 않도록 따로 보고합니다.

중복 키
RFC 8259는 키가 유일해야 한다(SHOULD)고만 말하고 중복일 때의 동작은 정의하지 않습니다. JavaScript와 Python은 마지막 것을, 일부 Go와 Java 파서는 문서 자체를 거부하고, 일부는 첫 번째를 택합니다. 여기서는 두 위치를 모두 알려 줍니다.
안전 범위를 벗어난 정수
2^53-1을 넘으면 JavaScript 숫자는 값을 정확히 담을 수 없습니다. 경고에는 JSON.parse가 대신 돌려줄 값이 함께 표시됩니다.
바이트 순서 표식
앞에 붙은 U+FEFF는 여기서는 받아들이고 보고합니다. 브라우저와 Node의 JSON.parse는 이를 그대로 거부하기 때문입니다.
아주 깊은 중첩
이 파서는 반복형이라 깊이 제한이 없지만, 받아 쓰는 쪽은 대개 제한이 있습니다. 이 머신에서 측정한 결과 V8은 약 4,800단계보다 깊은 구조의 직렬화를 거부합니다. 읽을 수 있는 문서가 다시 써낼 수 없는 문서일 수 있다는 뜻입니다.

문법뿐 아니라 구조도 검증하기

문법 검증은 문서가 형식에 맞는다는 것만 알려 줄 뿐, 기대한 내용이 들어 있는지는 알려 주지 않습니다. 그건 JSON Schema의 몫으로, 필수 속성과 타입과 제약을 기술합니다. 저희 스키마 생성기는 샘플 페이로드에서 출발점이 될 스키마를 만들어 줍니다.

How to do this in code

코드로 유효성을 확인하고, 거기서 쓸 만한 오류 정보를 뽑아내는 방법입니다.

js JavaScript

표준 라이브러리에는 예외를 던지지 않는 검증기가 없어서, try/catch가 곧 API입니다.

function validate(text) {
  try {
    JSON.parse(text);
    return { ok: true };
  } catch (e) {
    // Modern V8 includes a (line L column C) suffix in the message.
    return { ok: false, message: e.message };
  }
}
py Python

JSONDecodeError는 msg, lineno, colno, pos, doc을 담고 있어 대부분의 런타임보다 구조화된 정보를 줍니다.

import json

try:
    json.loads(text)
except json.JSONDecodeError as e:
    print(f"{e.msg} at line {e.lineno} column {e.colno} (char {e.pos})")
sh Shell

jq empty는 입력을 파싱하고 아무것도 출력하지 않아서, CI 스크립트 안의 유효성 검사로 깔끔하게 쓸 수 있습니다.

# jq exits non-zero and prints the position on failure
jq empty input.json

# Python, no extra install
python -m json.tool input.json > /dev/null
go Go

Go는 행이 아니라 바이트 오프셋을 알려 주므로 줄바꿈은 직접 세어야 합니다.

if !json.Valid(data) {
    // Valid() gives no position. To get one, decode and
    // inspect the SyntaxError:
    var v any
    if err := json.Unmarshal(data, &v); err != nil {
        var se *json.SyntaxError
        if errors.As(err, &se) {
            line := 1 + bytes.Count(data[:se.Offset], []byte("\n"))
            return fmt.Errorf("%v at line %d", se, line)
        }
    }
}

자주 묻는 질문

다른 검증기는 하나만 보고하는데 왜 여러 개를 보고하나요?
파서가 멈추지 않고 복구하기 때문입니다. 문제를 보고한 뒤 다시 동기화해서 계속 진행하므로, 끝쉼표와 작은따옴표 문자열과 따옴표 없는 키가 함께 있는 문서라면 세 가지를 한 번에 모두 보고합니다.
문자열이나 숫자 하나만 있어도 유효한 JSON인가요?
네, 2014년 RFC 7159부터 그렇습니다. 원래의 RFC 4627은 최상위 값이 객체나 배열이어야 한다고 요구했지만, 현재 명세인 RFC 8259는 어떤 값이든 허용합니다. 따라서 "hello", 42, null은 모두 완결된 유효한 JSON 문서입니다.
끝쉼표가 허용되는 경우도 있나요?
JSON에서는 없습니다. JavaScript, JSON5, 그리고 VS Code가 자체 설정 파일에 쓰는 JSONC에서는 허용됩니다. 받는 쪽이 JSONC를 받아들인다면 남겨도 되고, 아니라면 복구 도구가 제거해 줍니다.
주석은요?
JSON에는 설계상 없습니다. 더글러스 크락포드가 일부러 뺐는데, 사람들이 주석에 파싱 지시문을 넣어 쓰고 있었기 때문입니다. JSONC나 JSON5를 쓰거나, 설명을 "_comment" 같은 키로 옮기세요.