PC・モバイルのトラブル
よくあるJSONエラー:末尾カンマ、引用符、Unexpected token
無効なJSONを直す:末尾カンマ、単引用符、引用符なしのキー、Unexpected token。JSON.parseが失敗する理由と検証方法。
JSONエラーの多くは厳しい文法から来る。末尾カンマ、単引用符、引用符なしのプロパティ名、欠けたカンマ、括弧の不一致、不正なエスケープ、コメントだ。
JSONはJavaScriptオブジェクトに似て見えるが、より厳しい。プロパティ名と文字列には二重引用符が必要だ。
Unexpected tokenと出ても、示された文字は解析が止まった位置であり、元の誤りが始まった場所とは限らない。
JSONがinvalidと出た。壊れたファイル形式というより、小さな文法の問題が多い。次の七つがUnexpected tokenの大半を起こす。
JSONはなぜ壊れやすいのか
JSONは文法が厳しいデータ形式だ。JavaScriptのオブジェクトリテラルは似て見えても、そのままでは無効なJSONになり得る。標準JSONではプロパティ名と文字列に二重引用符が必要で、末尾カンマは不可、コメントは形式に含まれない。
1. 末尾カンマ(Trailing Commas)
最後のプロパティの後の余分なカンマが問題だ。標準JSONはこれを許さない。
無効
{
"name": "Alex",
"age": 30,
}
有効
{
"name": "Alex",
"age": 30
}
配列も同じだ。最後の要素の後のカンマを外す。
無効
[
"red",
"green",
]
有効
[
"red",
"green"
]
2. 二重引用符の代わりに単引用符
JavaScriptは単引用符をよく受け付ける。JSONは受け付けない。プロパティ名も文字列値も二重引用符でなければならない。
無効
{
'name': 'Alex'
}
有効
{
"name": "Alex"
}
3. 引用符なしのプロパティ名
JavaScriptではnameのように引用符なしで書けることがある。JSONではすべてのプロパティ名を二重引用符の文字列にする。
無効
{
name: "Alex",
age: 30
}
有効
{
"name": "Alex",
"age": 30
}
4. 値の間のカンマ漏れ
プロパティと配列要素の間にはカンマが必要だ。パーサーは欠けたカンマそのものではなく、次の引用符や括弧でUnexpected tokenを出すことがある。
無効
{
"name": "Alex"
"age": 30
}
有効
{
"name": "Alex",
"age": 30
}
5. 括弧の不足や余分
オブジェクトは { }、配列は [ ] を使う。入れ子のJSONでは ] が欠けたり } が余分だったり、両者が入れ替わると失敗する。開きと閉じの対を数える。
無効
{
"items": [1, 2
}
有効
{
"items": [1, 2]
}
6. 不正なエスケープ
JSON文字列の中で、バックスラッシュはエスケープを始める。"、\、\n などは有効だ。Windowsパスを C:\Users と書くと不正:\U は合法なJSONエスケープではない。バックスラッシュを二重にするか、パーサーはその文字で止まる。
無効
{"file":"C:\Users\Alex"}
有効
{"file":"C:\\Users\\Alex"}
7. JSON内のコメント
標準JSONにコメントはない。一部の設定ツールは // や /* */ を受け付ける(JSONC、JSON5など)。それは標準JSONではなく、JSON.parseは拒否する。
無効
{
// user name
"name": "Alex"
}
Unexpected tokenとは何か
パーサーが、その位置では許されない文字に出会ったという意味だ。報告される地点は読み取りが止まった場所だ。手前でカンマを落とすと、次のプロパティの引用符でエラーになることがある。文言はランタイムで違う。どのブラウザも同じ文を出すとは限らない。
Unexpected end of JSON inputとは何か
値が完了する前にテキストが終わった。欠けた } や ]、途中で切れた入力、空の本体、途中で切れたAPI応答が典型だ。原因は一つに限らない。
JSON.parse()はなぜ失敗するか
JSON.parse()は有効なJSONテキストだけを受け付ける。これは成功する:
const text = '{"name":"Alex"}';
const data = JSON.parse(text);
これは失敗する。単引用符はJSONではない:
const text = "{'name':'Alex'}";
JSON.parse(text);
正確なエラー文はJavaScriptランタイムに依存する。メッセージはヒントとして扱い、その位置付近のカンマ、引用符、括弧を調べる。
JavaScriptのオブジェクトリテラルは { name: 'Alex' } のように書ける。有効なJSONは { "name": "Alex" } のように、二重引用符の名前と文字列、末尾カンマなし、コメントなしでなければならない。
- JSONテキスト
- パーサーがトークンを読む
- 有効なデータ、または Unexpected token
JSONエラーを早く見つける方法
この順で進める。ファイル全体を書き直して始めない。
- validatorにJSONを通す。
- 最初に報告されたエラーを読む。
- 報告位置より少し手前を見る。
- カンマを確認する。末尾と欠けたもの。
- 引用符を確認する。二重引用符のみ。
- { } と [ ] を合わせる。
- 文字列内のバックスラッシュエスケープを確認する。
- strict JSONが必要ならコメントを除く。
よくある修正の早見:
| 問題 | 修正 |
|---|---|
| 末尾カンマ | 最後の項目の後のカンマを消す。 |
| 単引用符 | 名前と文字列に二重引用符を使う。 |
| 引用符なしのキー | プロパティ名を二重引用符で囲む。 |
| 欠けたカンマ | プロパティや配列要素の間にカンマを入れる。 |
| 欠けた括弧 | すべての { } と [ ] の対を閉じる。 |
| 不正なエスケープ | 合法なエスケープを使うか、パスのバックスラッシュを二重にする。 |
| コメント | 標準JSONなら // と /* */ を除く。 |
ブラウザでJSONを検証して整形する
NEXNARA JSON整形・検証・比較はこの端末でJSONを確認できる。
検証、2スペース・4スペース・タブでの整形、minify、二つの文書の比較(JSON Diff)、.jsonファイルを開ける。解析はブラウザのJSON.parseであり、evalは使わない。
5 MBより大きい文書は遅くなることがある。15 MBより大きいテキストはブラウザで処理しないので、ページが応答したままになる。
JSONの処理そのものはブラウザ内で行われる。このツールではテキストをNEXNARAサーバーへ送らない。広告や他のサイト機能はネットワークを使う。それは処理とは別だ。
無効なJSONを確認するならJSON整形・検証・比較を開き、テキストを貼り付けてほしい。
FAQ
JSONが Unexpected token と言うのはなぜ?
パーサーがその位置で許されない文字に出会った。本当の誤り—欠けたカンマや単引用符—はその直前にあることが多い。
JSONで末尾カンマは許される?
いいえ。標準JSONは最後のプロパティや配列要素の後のカンマを許さない。JavaScriptのオブジェクトリテラルはしばしば許す。
JSONに単引用符は使える?
いいえ。プロパティ名と文字列は二重引用符でなければならない。
JSONにコメントを含められる?
標準JSONではできない。一部のツールはコメント付きのJSONCやJSON5を受け付けるが、JSON.parseはそれでも拒否する。
JSON.parse()はなぜ失敗する?
文字列が有効なJSONではないからだ。末尾カンマ、単引用符、引用符なしのキー、コメント、途中で切れた値が典型だ。正確なメッセージはランタイムに依存する。
JSONが有効かどうかはどう確認する?
JSON整形・検証・比較のようなvalidatorに貼るか、コンソールでJSON.parseを呼ぶ。例外が出れば、そのテキストは有効なJSONではない。