JSON 尾逗號為什麼會報錯
結論:尾逗號在 JavaScript 裡合法,在 JSON 裡是語法錯誤。本文給出報錯原文、RFC 依據、三種改法,以及為什麼不要靠「刪逗號」蒙混過介面。

結論:JSON 全文不允許尾逗號,報錯時先用格式化工具定位最後一個逗號並刪除;需要寬鬆語法時只在本機用 JSON5 或 JSONC 解析,發給其他系統仍必須輸出標準 JSON。
因為標準不允許。
{
"name": "demo",
"size": 12,
}
JSON.parse 會拋 SyntaxError: Expected double-quoted property name in JSON at position 34。
Chrome 的說法是 Unexpected token } in JSON at position 34,Node 更囉嗦一點,但指向的都是同一個位置:} 前面那個逗號。
報錯到底在說什麼
RFC 8259 的物件語法是:
object = begin-object [ member *( value-separator member ) ] end-object
方括號表示「可省略」,星號表示「零次或多次」。翻成白話:成員之間才需要逗號,最後一位後面直接接 }。
解析器讀到逗號時已經準備接收下一個成員名稱,結果下一個字元是 },於是判定語法錯誤。陣列同理,[1, 2, 3,] 一樣報錯,只是錯誤位置落在 ] 上。
為什麼大家總覺得尾逗號是合法的
因為 JavaScript 物件字面量從 ES5 起就允許尾逗號,Python 的列表、Go 的複合字面量也允許。寫程式時習慣了,切換到 JSON 就順手帶上。另外不少編輯器會自動補逗號,貼上時也很容易多出來。
還有一個更隱蔽的來源:手寫範本拼 JSON。字串拼接時迴圈條件寫成 i <= length,最後一個元素後面就多了一個逗號。
三種改法
改法一:刪掉。 手動場景最直接。用本站的 JSON 格式化 貼進去,錯誤會定位到行列。
改法二:用 JSON5 或 JSONC 解析。 這兩種超集允許尾逗號,適合本機設定。但如果這段資料要發給介面、寫進資料庫、進訊息佇列,就不該指望對方也支援超集。
改法三:別手拼。 產生端一律用 JSON.stringify、json.dumps、Jackson 之類的序列化器,讓函式庫負責逗號。手拼字串是最常見的尾逗號來源,也順帶解決了轉義問題。
順手檢查這幾處
| 位置 | 常見錯誤 |
|---|---|
| 迴圈拼接 | 條件寫成 <=,結尾多一個逗號 |
| 複製貼上 | 從 JS 檔貼物件字面量,帶上了尾逗號 |
| 範本引擎 | 範本裡寫死逗號,迴圈裡又拼一次 |
| 手動編輯 | 刪了最後一個欄位,逗號沒跟著刪 |
常見問題
為什麼 JavaScript 能寫尾逗號,JSON 不行?
JavaScript 物件字面量從 ES5 起就允許尾逗號,Python 清單與 Go 複合字面量也允許,寫程式時很容易順手帶上。JSON 依 RFC 8259,只允許成員之間有逗號,最後一個成員後面直接接 } 或 ]。從 JS 檔貼物件字面量到 .json 檔,就是最常見的來源。
是否可以用 JSON5 或 JSONC 相容尾逗號?
可以,但只適合本機設定。這兩種超集允許尾逗號,解析器讀得懂;一旦資料要發給介面、寫進資料庫或進訊息佇列,對方按標準 JSON 解析仍會報錯。跨系統傳輸必須在產生端輸出標準 JSON。
尾逗號報錯後應該先檢查哪裡?
先看錯誤訊息給出的位置,通常是 } 或 ] 前面那個逗號。再檢查三個常見來源:迴圈拼接把條件寫成 i <= length、從 JS 檔複製貼上的物件字面量、以及範本裡寫死逗號後又拼了一次。用格式化工具貼一次,行列會直接指到出錯位置。