📚 EVEDAYS Guide Book
[開発者ツール]•6 分で読める

JSONのパースが失敗する5つの理由と、大きな数値の精度の罠

1. JSONは見た目より厳格


JSONはJavaScriptのオブジェクトリテラルに似ていますが、文法はずっと狭いものです。RFC 8259とECMA-404が定義しており、JavaScriptで通る書き方がJSONでは通らないことが多々あります。

2. パースが失敗する5つの原因


① 末尾のカンマ(trailing comma)
{"a": 1, "b": 2,} — 最後の要素の後のカンマはエラーです。JavaScriptでは許されますがJSONでは不可です。

② キーがダブルクォートで囲まれていない
{a: 1} — キーは必ずダブルクォートで囲んだ文字列でなければなりません。

③ シングルクォートの使用
{'a': 'b'} — JSONはダブルクォートのみを認めます。

④ コメント
// 説明も/* */もJSON標準には存在しません。設定ファイルでコメントを使うにはJSONCやJSON5などの拡張形式が必要です。

⑤ 特殊値
NaN、Infinity、undefinedはJSONにありません。数値がない状態はnullか文字列で表現します。

このほか、文字列内に生の改行を入れるのもエラーです。\nにエスケープしてください。

3. エラー位置の読み方


パーサーは通常「position 42」のような位置を示しますが、実際の原因はそれより前にあることが多いです。クォートを1つ書き忘れると、パーサーは後続を文字列の一部として飲み込み、はるか後方で初めて失敗します。

フォーマッターに通して構造を展開すると、入れ子のずれを目で見つけやすくなります。

4. 大きな数値の精度の罠


これは文法エラーではなく値が静かに変わる問題であるため、より危険です。

JavaScriptの数値は倍精度浮動小数点なので、整数を正確に表現できる上限は次のとおりです。

Number.MAX_SAFE_INTEGER = 9007199254740991

これより大きい整数をJSON.parseで読み込むと値が静かに変化します。たとえば12345678901234567890はパース後に12345678901234567000となります。エラーも警告も出ません。

問題になる場面
  • Snowflake方式の64ビットID(Twitter、Discordなど)

  • データベースのBIGINT主キー

  • 補助単位で表した大きな金額


  • 対処法
    標準的な解決策は、サーバー側でこうした値を文字列としてシリアライズすることです({"id": "12345678901234567890"})。クライアントで数値として扱う必要があれば、BigIntとカスタムreviverを使います。

    5. JSONの派生形式


    | 形式 | 違い | 用途 |
    |---|---|---|
    | JSON | 標準 | APIレスポンス、データ交換 |
    | JSONC | コメント可 | VS Codeの設定など |
    | JSON5 | コメント・末尾カンマ・シングルクォート可 | 人が手書きする設定ファイル |
    | NDJSON / JSON Lines | 1行に1つの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