幾乎每個「Unexpected token in JSON」錯誤,都來自同一份很短的失誤清單。以下逐一列出與修法。(不熟這格式?先看 JSON 是什麼。)
這些是我們工具實際印出來的訊息。 我們把六段壞掉的 JSON 餵進 JSON 格式化工具,把回來的字一字不改記下來,方便你比對眼前那句:
{"a":1,}→ Expected double-quoted property name in JSON at position 7 (line 1 column 8){'a':1}與{a:1}→ Expected property name or ’}’ in JSON at position 1 (line 1 column 2){"a":{"b":1}→ Expected ’,’ or ’}’ after property value in JSON at position 12 (line 1 column 13){"a":undefined}→ Unexpected token ‘u’, ”{“a”:undefined}” is not valid JSON{"a":1 "b":2}→ Expected ’,’ or ’}’ after property value in JSON at position 7兩件值得知道的事:單引號字串與沒加引號的鍵會產生完全相同的訊息,因為剖析器兩種情況都在同一個位置放棄。另外訊息的字句來自瀏覽器自己的 JSON 剖析器,所以 Firefox 與 Safari 的講法不一樣 —— 可以依賴的是那個位置數字。行列標註是我們的工具自己加上去的。
1. 多餘的逗號
JSON 不允許最後一項後面還有逗號:
{ "a": 1, "b": 2, } ← 無效
{ "a": 1, "b": 2 } ← 有效
2. 單引號
字串與屬性名必須用雙引號:
{ 'name': 'Ann' } ← 無效
{ "name": "Ann" } ← 有效
3. 屬性名沒加引號
不像 JavaScript 物件,JSON 的鍵一定要加引號:
{ name: "Ann" } ← 無效
{ "name": "Ann" } ← 有效
4. 註解
JSON 不能有註解。解析前把 // 與 /* */ 移除。
5. 括號錯誤或缺漏
每個 { 都要有 }、每個 [ 都要有 ]。常見的是括號混用,或忘了把多筆資料用陣列 [ … ] 包起來。
少一個括號,是所有錯誤裡「回報位置離錯誤最遠」的那一個。{"a":{"b":1} —— 少一個右大括號 —— 給的是
✗ JSON syntax error: Expected ',' or '}' after property value in JSON at position 12 (line 1 column 13) [L1:13]
位置 12 是輸入的結尾,因為解析器要一直讀到沒有字元可讀,才知道少了東西。錯誤在左邊那個開頭的 {;回報在最右邊。對照少一個逗號的 {"a":1 "b":2},它給的是
✗ JSON syntax error: Expected ',' or '}' after property value in JSON at position 7 (line 1 column 8) [L1:8]
同一句訊息,但位置 7 剛好落在逗號本來該在的地方。當回報的欄位是檔案的最後一個字元時,要去找沒關的括號,而不是去讀它指的那一行。
6. 非數值的值
NaN、Infinity、undefined 都不是合法 JSON。請改用數字、字串或 null。
「不是數字」的值又是另一種失敗方式,而訊息本身就說了。{"a":undefined} 給的是
✗ JSON syntax error: Unexpected token 'u', "{"a":undefined}" is not valid JSON
注意解析器是把你整段輸入原樣引回來,而不是給一個欄位:它連把 undefined 當成一個值來解讀都做不到,所以不存在「哪個合法 token 出錯」的位置。NaN 和 Infinity 也是同樣的失敗。JSON 表達「沒有值」只有一種寫法,就是 null。
最快的修法:驗證
與其用肉眼找,不如把 JSON 貼進會指出錯誤位置的驗證工具:
- JSON 格式化與驗證——美化、壓縮、驗證,並標出語法錯誤的位置。
- 之後要放進試算表?把 JSON 轉成 CSV 或 Excel。
修好上面六個失誤,絕大多數「JSON 無效」的問題就會消失——全程在你的瀏覽器本機執行,連機敏資料也不外流。
實際範例:修正前後
以下這段同時踩到上面三個雷:
{
'user': "Ann",
"roles": ["admin", "editor",],
"active": True,
}
解析器只會停在第一個遇到的問題,丟出類似 Unexpected token ' at position 4 的簡短訊息——即使實際上有三個錯。一次修好:把單引號換成雙引號、刪掉兩個多餘逗號、把布林值改小寫:
{
"user": "Ann",
"roles": ["admin", "editor"],
"active": true
}
要特別小心 True、False、None——那是 Python 的寫法。JSON 只認得小寫的 true、false 與 null。
JSON 不是 JavaScript 物件
多數錯誤都源自「把 JSON 當成 JavaScript 原始碼」。其實不是——JSON 是一種語法更嚴格的文字格式:
- 鍵一律是加引號的字串,不能是裸識別字;
- 只接受直的雙引號,不接受單引號、反引號,也不接受文書軟體自動換成的彎引號;
- 不能有多餘逗號、註解或函式呼叫;
- 數字不能以正號或前導零開頭,結尾也不能只有一個點。
只要有辦法,就用真正的序列化器產生 JSON——JavaScript 用 JSON.stringify、Python 用 json.dumps——別自己手動拼字串,它每次都會把引號與跳脫處理正確。
常見問答
為什麼錯誤說「position 0」?
輸入是空的、開頭有位元組順序記號(BOM),或那其實是一頁 HTML 錯誤頁而不是 JSON。先確認 API 到底回了什麼,再怪語法。
設定檔可以留註解嗎?
純 JSON 不行。編輯時可用 JSON5 或 JSONC,或改用 YAML,送進嚴格解析器前再把非標準的部分清掉。
檔案太大打不開怎麼辦?
先格式化,讓層次顯現,再把不需要的分支收合起來。貼進 JSON 格式化工具 一步就能同時做到。