JavaScriptのJSON.parse()
JavaScriptのJSON.parse()を学びましょう。文字列からオブジェクトへの変換、reviver関数、エラーハンドリング、信頼できないJSON入力のセキュリティ上の考慮事項を解説します。
詳細な説明
JSON.parse() は、JSON形式の文字列をネイティブのJavaScript値に変換するための組み込みメソッドです。JSON.stringify() の対になるもので、APIからJSONデータを受信する、localStorageから読み取る、JSONファイルを処理する際に使用されます。
メソッドシグネチャ:
JSON.parse(text, reviver?)
- text: パースするJSON文字列(有効なJSONでなければならない)
- reviver: パースされた値を変換するオプションの関数
基本的な使い方:
const data = JSON.parse('{"name":"Alice","age":30}');
console.log(data.name); // "Alice"
console.log(data.age); // 30
reviverパラメータ:
reviver関数はパース中のすべてのkey-valueペアに対して呼び出され、値を変換できます。一般的な用途は、日付文字列をDateオブジェクトに戻すことです:
const data = JSON.parse(jsonString, (key, value) => {
if (key === 'createdAt' || key === 'updatedAt') {
return new Date(value);
}
return value;
});
reviverはパースされたツリーをリーフからルートへと走査するため、ネストされた値はその親よりも先に変換されます。
エラーハンドリング:
JSON.parse() は入力が有効なJSONでない場合に SyntaxError をスローします。常にtry/catchブロックで囲む必要があります:
try {
const data = JSON.parse(userInput);
} catch (error) {
console.error('Invalid JSON:', error.message);
}
エラーメッセージはJavaScriptエンジンによって異なりますが、通常はパースが失敗した位置を含みます。
セキュリティ上の考慮事項:
古いJavaScript環境では、開発者がJSONのパースに eval() を使用することがありましたが、eval() は任意のコードを実行するため非常に危険です。JSON.parse() はこの点で安全です。データのパースのみを行い、関数の実行や変数へのアクセスはできません。ただし、信頼できないJSONのパースは、パースされたオブジェクトを無差別に他のオブジェクトにマージする場合、プロトタイプ汚染攻撃のベクターとなり得ます。lodash.merge などのライブラリには、パースされたJSONの __proto__ や constructor のようなキーがオブジェクトプロトタイプを変更できる脆弱性がありました。
開発者がよくやるミス:
よくあるエラーは、すでにJavaScriptオブジェクトである値に対して JSON.parse() を呼び出すことで、JSON.parse() は文字列を期待するため失敗します。パース前に typeof value === 'string' を確認してください。もうひとつのミスはエラーケースを処理しないことで、APIからの不正なレスポンスがアプリケーション全体をクラッシュさせます。また、ループ内でJSONをパースしてパフォーマンスコストに気づかないこともあります。一度パースしてから結果をキャッシュしてください。さらに、JSON.parse("undefined") や JSON.parse("") はいずれも有効なJSONではないためエラーをスローします。
ベストプラクティス:
JSON.parse() の周囲には常にtry/catchを使用してください。構造を盲目的に信頼するのではなく、パースされたデータを期待するスキーマに対して検証しましょう。JSONがネイティブにサポートしていない日付、BigInt値、その他の型を変換するためにreviver関数を使用してください。大きなJSON文字列をパースする際は、メモリ効率を高めるためにストリーミングパーサーを検討しましょう。
ユースケース
REST APIのfetch()呼び出しからJSONレスポンスをパースし、reviver関数を使用してISO 8601の日付文字列を自動的にJavaScript Dateオブジェクトに変換する。