[開発者ツール]•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となります。エラーも警告も出ません。問題になる場面
対処法
標準的な解決策は、サーバー側でこうした値を文字列としてシリアライズすることです(
{"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レスポンスには個人情報やトークンが含まれることが多いため、外部サーバーへ送信しないツールを使うほうが安全です。