日本語

開発者ツール · JSON フォーマッタおよびバリデータ

JavaScript オブジェクト リテラルと JSON: 一重引用符が検証に失敗する理由

· 仕組み

json 開発者ワークフロー 検証

JavaScript オブジェクト リテラルと JSON: 一重引用符が検証に失敗する理由を JSON トークンと正確な検証境界で示します
オリジナル ToolAcre ベクトル イラスト

JavaScript コンソールによって出力されるオブジェクトは JSON のように見えますが、通常はそうではありません。この投稿では、正確な違い (引用符、引用符で囲まれていないキー、未定義、関数) をリストし、それぞれがバリデーターをトリップする場所を示します。

コンソールから出てきたのに、なぜ無効なのでしょうか?

コンソールから出てきたのに、なぜ無効なのでしょうか? — 開発者コンソールは、JavaScript 値を、保証された JSON シリアル化としてではなく、JavaScript ソースのようなテキストとして表示します。コピーされたオブジェクトには、裸のプロパティ名、一重引用符で囲まれた文字列、`undefined`、またはブラウザー固有の注釈が含まれる場合があります。これらはすべて、JavaScript エンジンや人間の読者には理解できますが、`.json` ファイルでは即座に失敗します。このファイルの文法は意図的に小さく、実行可能コードから独立しています。

`{name: "Ada", active: true, missing: undefined}` を検討してください。中かっこ、コロン、およびブール値は JSON に似ていますが、最初の裸のキーがすでにオブジェクト メンバーのルールに違反しているため、`undefined` は後で失敗します。 ToolAcre は最初のサポートされていない文字または値を行と列で報告するため、変換は順番に行うのが最適です。

文字列には二重引用符を使用する必要があります

文字列には二重引用符を使用する必要があります。JSON は、必要に応じてバックスラッシュ エスケープを使用して、`"` で囲まれた文字として文字列を定義します。一重引用符には文字列の区切り文字としての役割はありません。バリデーターが `'Ada'` を満たす場合、文字列を開始してからその内容に異議を唱えることはありません。開始アポストロフィー自体を拒否します。 JavaScript では独自のリテラルに対していずれかの引用スタイルが許可されていますが、これはプロパティ名と文字列値にも同様に当てはまります。

引用符の変換には、すべてのアポストロフィをグローバルに置き換えるよりも注意が必要です。 `Ada's profile` などのテキスト内のアポストロフィは、値が二重引用符で囲まれると通常の内容になりますが、その内容内の既存の二重引用符はエスケープする必要があります。有効な JSON 形式は `"Ada's "profile""` です。

キーは引用符で囲まれた文字列である必要があります

キーは引用符で囲まれた文字列である必要があります。JavaScript オブジェクト リテラルでは、`{name: 1}` などの識別子形式の名前と、`{[expression]: 1}` などの計算された名前が許可されます。 JSON ではどちらの速記も許可されません。左中括弧またはコンマの後、次のメンバーは二重引用符で囲まれた文字列で始まり、その後にコロンが続く必要があります。有効な表現は `{"name": 1}` です。 `n` を指すバリデータは、引用が必要とされた正確な場所を識別します。

すべてのキーを引用符で囲むと、スペース、ハイフン、予約語の周りの曖昧さも解消されます。 JavaScript ではそのような場合に異なるソース構文が必要になる場合がありますが、JSON では 1 つの一貫したルールが使用されます。`"display-name"`、`"first name"`、および `"default"` はすべて通常のメンバー名です。数字のように見えるキーも文字列です。

値 JSON には単に値がありません

値 JSON には単純に存在しません。その値の語彙は、オブジェクト、配列、文字列、数値、`true`、`false`、および `null` です。 `undefined`、`NaN`、`Infinity`、関数、正規表現、BigInt、または Date リテラルはありません。コメントは文法に含まれておらず、数値には 16 進数、2 進数、先頭のプラス記号、または JavaScript 数値区切り文字を使用できません。借用された各構成は、最終的に、有効な JSON 値を開始または継続できない文字に到達します。

変換には、スペルのトリックではなく、データの決定が必要です。明示的な空の値がアプリケーション コントラクトに一致する場合にのみ、`undefined` を `null` に置き換えます。それ以外の場合は、メンバーを削除するか、実数値を指定してください。日付を合意された文字列としてエンコードします (多くの場合 ISO 8601)。 JSON トークンを作成する代わりに、受信 API に従って非有限数を表します。

実用的な例: コンソール ダンプを有効な JSON に変換する

作業例: コンソール ダンプを有効な JSON に変換する — `{name: 'Ada', active: true, score: NaN, updated: new Date()}` から開始します。 `name`、`active`、`score`、`updated` は二重引用符で囲みます。名前の値を二重引用符で囲まれた文字列に変更します。使用できないスコアを `null` にすることを決定し、コンストラクター式を、生成されるはずだった実際のタイムスタンプ文字列に置き換えます。現在、ドキュメントには JSON メンバーと値のみが含まれています。

完成した形状は `{"name":"Ada","active":true,"score":null,"updated":"2026-03-21T10:00:00Z"}` になる可能性があります。最初のエラーによって後の JavaScript のみの構文が隠される可能性があるため、修復の各カテゴリの後に検証してください。受け入れられた結果をフォーマットすると、それ以上の変換を実行せずにその構造が公開されます。

逆トラップ — 非常に大きな整数や __proto__ キーなど、JavaScript が異なる方法で読み取る有効な JSON

逆トラップ - 有効な JSON は、解析後に JavaScript 固有の動作や制限を受ける可能性があります。 JSON 数値には文法に精度制限が組み込まれていませんが、JSON.parse は JavaScript 数値値を生成します。したがって、安全範囲を超えた整数はサイレントに丸められます。すべての数字が重要な場合は、識別子を文字列としてエンコードするか、構文チェックの成功を信頼するのではなく、任意精度の数値を保持するように設計されたパーサーとデータ型を使用します。

メンバー名 `"__proto__"` も有効な JSON であり、 JSON.parse はそれを独自のデータ プロパティとして作成します。アプリケーション コードが、安全でない代入またはマージ動作を使用して、解析されたプロパティを別のオブジェクトにコピーすると、後で問題が発生する可能性があります。検証により、テキストが JSON 文法に従っていることが証明されます。すべてのキーがすべての消費者にとって安全であることを証明するものではありません。

これでカバーされない内容

これでカバーされないもの — コメント、末尾のカンマ、引用符で囲まれていない名前、または一重引用符で囲まれた文字列を意図的に受け入れる JSON5、JSONC、および構成言語。これらの形式は、さまざまなオーサリングの問題を解決するため、独自の文法を実装するパーサーを必要とします。厳密な JSON バリデーターは、追加の構文を受け入れると、標準の JSON を本当に必要とする API、パッケージのメタデータ、その他の宛先に対して結果が誤解を招く可能性があるため、それらをサイレントに再解釈すべきではありません。

この区別により、任意の JavaScript 評価も除外されます。オブジェクト リテラルをデータに変換するためだけに貼り付けたテキストを `eval` または関数コンストラクターを通じて実行すると、ゲッター、呼び出し、またはその他の敵対的な式が実行される可能性があります。ソースが管理下の信頼できる JavaScript である場合は、JSON.stringify を使用して実際の値をシリアル化します。ソースが信頼できないテキストである場合は、それを実行しないでください。

要点: リテラルはコード、JSON はデータです

要点: リテラルはコード、JSON はデータです。視覚的な類似性によって文法が互換性があるわけではありません。 JSON には二重引用符で囲まれた文字列とメンバー名が必要で、少数の固定値セットのみが許可され、コメントや実行可能な式は含まれません。行と列の診断は、コピーされたソースがその文法から離れた最初の場所をマークします。その点を修復して再度検証することは、コンソール ダンプに広範な検索と置換を適用するよりも信頼性が高くなります。

JavaScript 値を制御する場合は、コンソール表現をコピーするのではなく、JSON.stringify を使用して JSON を生成します。テキストを受信した場合は、宣言された形式のパーサーのみを使用してテキストを解析し、ショートカットとして実行しないでください。 JSON 検証が成功すると、数値精度、スキーマ準拠、または安全なダウンストリーム プロパティ処理ではなく、構文が確立されます。