私が造る Toolz.dev、そしてその前に私は何年もかけて出荷した WordPress プラグインと Laravel API. そのすべてで、私が最も時間を無駄にした単一のエラーメッセージは、" のいくつかのバリエーションです位置428." で予期しないトークン それはほとんど何も教えてくれません 行も列もなく、それが名前を付ける位置は、しばしば間違っていることを過ぎて数文字になります 手でミニ化された塊の文字を数えるか、ペイロード全体をエディタに貼り付けて目を細めることになります JSON バリデータ したがって、私は二度とそれを行う必要はありません。これが、JSON の動作と、JSON の検証が見た目よりも難しい理由についてのガイドです。
tl;dr: JSON バリデータは、テキストを RFC 8259 の文法に照らしてチェックし、テキストが壊れていると、最初のエラーの正確な行、列、文字を、予期していたものに基づいて表現して教えてくれます。また、通常のパーサーが隠しているもの、つまり最後の値まで静かに折りたたまれる重複キーも捕捉し、有効なドキュメントの構造 (オブジェクト、配列、キーのカウント、ネスト深さ、バイト サイズ) を報告します。フォーマッタではありません。フォーマッタは、入力がすでに有効であると仮定します。バリデータは、入力が正しくない場合に正確に到達するものです。
JSONが有効であるということはどういう意味ですか?
JSONは文法が厳密な小さな形式です 現在の標準は RFC 8259、 並ぶ ECMA-404、そしてそれらの間には、有効な文書に含まれる可能性のあるものを正確に定義します。 JSONテキストは単一の値です。 その値は、オブジェクト、配列、文字列、数値、 true、 false、または null。 オブジェクトは中括弧で囲まれ、カンマ区切りで保持されます "key": value ペア. 配列は括弧で囲まれ、カンマ区切りの値を保持します. 文字列は二重引用符で囲まれます.決して単一引用符ではありません.数値は特定の形状に従い、先頭にゼロがなく、末尾に小数点もありません.コメントはありません.
その最後の文は、ほとんどの現実世界のJSONが間違っている場所です、なぜなら、手書きで書くJSONの人々の多くは実際にはJSONではないからです。 とのコンフィグファイルです // コメント、またはjavascriptソースからコピーされたオブジェクトで、シングルクォーテーションと末尾のカンマが問題ないもの、または誰かがフィールドを追加してぶら下がっているカンマを残した手編集のフィクスチャ。これらはすべて厳密なパーサーによって拒否され、バリデーター' のジョブは、肩をすくめるのではなく、特定の場所で拒否することです。
何年も前に JSON を学んだ人々を魅了するので、清算する価値のある点が 1 つあります。裸の価値とは、完全で有効な JSON ドキュメントです。 42 それ自体は有効なJSONです。 so is "hello"、 であり、また である true。 古い RFC 4627 は最上位がオブジェクトか配列であることを要求したが、2014 年にRFC 7159(後の8259)がそれに取って代わったときにその制限は取り除かれた。 ツールが教えてくれたら 42 JSON は有効ではありません。このツールは 10 年以上使用されていない仕様に従っています。
なぜJSON.parseはそのような悪いエラーレポーターですか?
専用のバリデータがその地位を獲得する理由は、言語に組み込まれたパーサが、悲しいパスを説明するためではなく、幸せなパスに最適化されているためです。 JSON.parse ブラウザでは、 がスローされます SyntaxError whose message is engine-specific and usually gives you a character offset with no line or column. V8 says "Unexpected token} in JSON at position 148." Firefox says "JSON.parse: 予期しない文字 at line 1 column 149." Safari says something different again.それらのどれもが何を期待していたかを教えてくれず、その位置は文字列の先頭から計測されるので、JSONが数行以上持っている瞬間には役に立たない。
Toolz.dev 上のバリデータは使用しません JSON.parse.テキスト自体を手書きの再帰降下パーサで歩き 行と列をそのまま追跡するので 停止すると 3 つの座標を すべて手渡すことができます 行 列 絶対文字のオフセットです さらに重要なのは その途中にあった文法規則を知っているので メッセージが特定されることです " 予期しないトークン " 取得 " 末尾にトレーリングカンマは許可されません " または " オブジェクトキーは二重引用符で囲まれた文字列でなければなりません " または " オブジェクトメンバーの後にカンマまたは末尾にブレースを期待しました " その違いは、ファイルを5 秒で固定して探すことの違いです。
また、コンパイラーが行うように、問題のある行の正確な文字の下にキャレットを描画します。 config ファイルの 34 行目を見ているときは、" 列 12" は問題ありませんが、a ^ 迷った見積もりの真下に座るほうが早い.
バリデータは名前でどのJSONの間違いをキャッチしますか?
これらは、私自身の作品でも、このようなツールのサポート スレッドでも、私が最も頻繁に見る失敗です。バリデータは、一般的なトークン エラーを報告するのではなく、それぞれに名前を付けます。
| 間違い | どんな感じか | なぜ無効なのか |
|---|---|---|
| 末尾のコンマ | {"a": 1,} や [1, 2,] |
JSON には末尾のカンマがありません。 standard's 文法では、閉じる中括弧または括弧の前にカンマを許可しません |
| 一重引用符 | {'name': 'Liton'} |
文字列とキーはダブルクォートを使用する必要があります; シングルクォートはJSONではなくJavaScriptの習慣です |
| 欠損コンマ | {"a": 1 "b": 2} |
最初のメンバー以降のすべてのメンバーの前にはカンマが必要です |
| コメント | {"a": 1} // note |
JSON にはコメント構文がありません; the // そして、その後のすべては予想外のコンテンツです |
| 引用符で囲まれていないキー | {name: "Liton"} |
キーは文字列であり、JavaScriptオブジェクトリテラルとは異なり、引用符で囲む必要があります |
| リーディングゼロ | {"n": 007} |
数値には先頭のゼロがない場合があります 007 は無効です; write 7 |
| 後小数点 | {"n": 5.} |
小数点以下の分数には少なくとも 1 桁が必要です |
| 生のコントロールキャラクター | 文字列内のリテラルタブまたは改行 | 文字列内の制御文字は、次のようにエスケープする必要があります \t、 \n、 などなど |
| NaN または Infinity | {"n": NaN} |
これらは JavaScript では有効ですが、JSON 値ではありません |
| 終端しない文字列 | {"a": "oops} |
終了引用符のない文字列は入力の最後まで実行されます |
これらのどれもが平易な言語のメッセージと位置を生成します。 leading-zero のケースは、専用のパーサーが役立つ理由を示す良い例です。 generic パーサーは読み取ります 007 数字として 0 そして、それを乗り越えます 7 " 追加コンテンツ、" として。を指しています 7、本当の問題が前の2 つのゼロの場合。 validatorは先頭の-ゼロパターンを最初にチェックし、それを直接伝えます。
重複キーは?
これは構文エラーでは全くないので、どんな構文エラーよりもプロダクションで私を噛んだものです これは有効なJSONです:
{
"timeout": 30,
"retries": 3,
"timeout": 60
}
RFC 8259 says the names within an object "SHOULD be unique," but it does not forbid duplicates, so a parser is required to accept this. RFC 8259 ではオブジェクト内の名前は " 一意であるべきで、 " しかし、それは重複を禁止しないので、パーサーはこれを受け入れる必要があります。 次に何が起こるか、トラブルが始まる場所です: 標準は重複した名前での動作は予測不可能であると述べ、実際にはほとんどすべてのパーサーが最後の値を保持し、以前の値を静かに破棄します。したがって、このオブジェクトは解析します {"timeout": 60, "retries": 3}、そして "timeout": 30 ファイルの上部に慎重に設定すると、警告もなく消えます。 2 人がコンフィグを編集したり、マージが間違ったり、テンプレート化ステップで同じキーが 2 回発行されたりすると、パーサーがフラグを立てないバグが発生します。
バリデーターがフラグを立てます。 duplicate-key detection はデフォルトでオンになっており、重複は合法であるため、エラーではなく警告として報告されます。ドキュメントはまだ有効ですが、同じオブジェクトに複数回表示されるすべてのキーが通知されます。行と a JSON ポインタ ネストされた構造内で見つけることができるパス。本当に重複が必要な場合は、チェックをオフにすることができます。ほとんどの場合、警告を確認することは、何が問題だったのかを理解した瞬間です。
バリデータはフォーマッタとどう違うのですか?
人々は言葉を同じ意味で使い 道具は重なり合いますが 答え方は異なります A JSON フォーマッタ takes JSON you already believe is valid and re-prints it with consistent indentation so a human can read.フォーマッターが壊れたJSONを手渡せば、それができる最善のことは拒否することです。 validator' s whole purpose is the broken case: it tells you where and why. Toolz.dev validatorは両方の仕事をします、なぜなら文書が有効であることを確認したら、すでに解析済みだからです、それで結果は同じパスでpretty-printsされます。 しかし、見出しの特徴はインデントではなく診断です。
隣接する道具についても同じ関係が成り立つ。 を JSON ミニファイア ペイロードを縮小するために空白をストリップします。これは有効な入力でのみ意味を持ちます。ザ JSON ソータ 安定した差分のためにキーを並べ替えます。, 再び有効な入力で。 the JSONエスケープとアンエスケープ ツールは文字列の中に JSON を埋め込むことを扱います。そして、 JSONPath テスター すでに確認したドキュメントが適切にフォーミングされているクエリー 検証は、それらすべての前に来るステップであるため、APIレスポンスまたはコンフィグファイルの動作が奇妙になるたびに最初に実行するステップで、これらがどのように組み合わされるかについてのより広範なツアーがあります JSON ツールの究極のガイド。
構造統計はあなたに何を教えてくれますか?
ドキュメントが検証すると、ツールはその形状を報告します: 含まれるオブジェクトと配列の数、キーの数、文字列、数値、ブール値、nullの数、ネストする深さ、文字とUTF-8 バイトの両方のサイズ。 decorationではありません。 なじみのないAPIレスポンスを渡されると、深さの数字はフラットレコードを扱っているのか深くネストされたツリーを扱っているのかを一目で教えてくれ、キーカウントはそれが解析する作業がどのくらいになるかを大まかに教えてくれます。
バイト数値は人々の予想よりも重要です。 request-size の制限、message-queue の制限、およびデータベースの列の制限は、ほとんどの場合、文字ではなくバイトで測定され、JSON に ASCII の外側に何かが含まれている瞬間に 2 つが異なります。 絵文字またはアクセント付き名前は、画面上では 1 文字ですが、ワイヤ上では 2、3、または 4 バイトです。ペイロードが 256 KB の制限にぶつかっている場合、文字数は誤解を招き、バイト数は減少しません。バリデータは真の UTF-8 バイト長を計算するため、表示される数値は制限がカウントしている数値になります。
使い方
私のワークフローは退屈で高速です、それがポイントです 統合が壊れたとき、私は生の応答本体をネットワークタブから直接コピーしてバリデータに貼り付けます それが有効であれば、緑の結果と統計は問題がどこか別の場所にあることを教えてくれます、彼らのデータではなく私のコードで、そして私は2 秒で原因のクラス全体を除外しました 無効であれば、私は行と列を取得し、修正し、次に進みます 私はコンフィグファイルを手編集しているとき、私はコミットする前に貼り付けます、主に私がいつも残しているように見える後続のカンマとコピーペーストから時折重複するキーをキャッチするために自分のキットを組み立てる人のために、バリデータは他の必需品と並んで座っています Web 開発者ツールキット。
プライバシーの角度も後付けではありません 最も検証する必要があるJSONの人々は、まさに彼らが最も注意すべきJSONです: トークンを運ぶAPI応答、資格情報を含む構成ファイル、顧客データを含むペイロード バリデーターが行うことはすべて、ブラウザー、JavaScript、マシン上で行われます アップロード、ログ、保存されるものは何もありません バリデーション中にネットワークタブを開くか、インターネットから切断してツールが機能し続けるのを見ることによって証明できます。
よくある質問
JSONが正常に見えるときに無効であると言うのはなぜですか?
最も一般的な理由は、閉じる中括弧または括弧の前にコンマを引くこと、JSON が二重引用符を必要とするシングル クォーテーション、2 人のメンバー間のコンマが欠落していること、またはコメントであり、JSON はまったく許可していません。特に大きなファイルでは、4 つすべてが目で見逃しがちです。バリデータはどれを見つけたかを名指しし、正確な行と列を指定するため、ドキュメント全体をスキャンする代わりに、停止した文字にまっすぐにジャンプします。
単一の数値または文字列は、それ自体で有効なJSONですか?
はい。 RFC 8259 では、任意の JSON 値は完全な JSON テキストであるためです 42、 "hello"、 true、そして null すべて自分で検証します。 「最上位はオブジェクトか配列でなければならない」というルールは、古い RFC 4627 から来たもので、2014 年に削除されました。裸の値を拒否するツールは、廃止された仕様に従っています。
バリデータは私のデータを変更またはアップロードしますか?
いいえ ブラウザでテキストを解析し どこへも送信しません 有効な文書では 利便性を考慮して かなり印刷されたコピーを生成しますが そのコピーはローカルで生成され 原本は送信もログも保存もされません サーバー往復も存在しないため ページが読み込まれると ネットワークが切断された状態でも ツールは動作します。
JSON がまだ有効であるのに、重複キーを気にする必要があるのはなぜですか?
なぜなら、重複はほとんどの場合、意図しなかったデータ損失を意味するからです。 標準では、重複キーを許可しますが、その処理は未定義のままにし、実際には、パーサーは最後の値のみを保持し、残りをドロップします。 a config where timeout 2 回静かに表示され、最初の設定が失われます。バリデータは、その位置で繰り返されるすべてのキーについて警告します。これは通常、マージの不良やコピーペーストの間違いを発見した瞬間です。
これにより、tsconfig や VS Code 設定ファイルなどのコメントを使用して JSON を検証できますか?
いいえ、それは意図的です。それらのファイルは、ルールを緩和する別の形式であるコメント付き JSON (JSONC) または JSON5 です。バリデータは、厳密な RFC 8259 をターゲットにしているため、コメントにエラーとしてフラグを立てます。 config ファイルにコメントが必要な場合、それは、標準が許可するものを超えて拡張された JSON ではなく、YAML や TOML など、その形式用に構築されたものである必要があるという信号です。
JSONの検証とフォーマットの違いは何ですか?
Validatingは、テキストがJSON文法に従っているかどうかをチェックし、従っていない場合は、どこで壊れているかを正確に伝えます フォーマットでは、テキストがすでに有効であると仮定し、読み取り可能性のためにその空白を調整する必要があるときにバリデーターにリーチします; すべてが問題なく、単に読み取り可能であることを望むときにフォーマッターにリーチします このツールは両方を行いますが、存在する理由は診断です。
どのくらいの大きさのファイルを検証できますか?
快適に数十メガバイトに, あなたのブラウザによってのみ制限& #39; sメモリ, 全体の文書は、あなたのデバイス上で1 つのパスで解析されているため、. there is no upload size cap because there is no upload. for a genuinely huge file, in the gigabytes, a streaming command-line validator is the better instrument, since the browser holds the whole text in memory at once.



