SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data 表示解析器成功讀到了一個完整的 JSON 值 —— 然後在它後面又發現了更多非空白內容。JSON 頂層只允許一個值,因此後面接著的任何東西都是錯誤。下面說「多餘資料」是怎麼來的以及怎麼修。
錯誤長什麼樣
// Firefox
SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data
at line 1 column 18 of the JSON data
// V8 (Chrome / Node / Edge)
SyntaxError: Unexpected non-whitespace character after JSON at position 17
SyntaxError: Unexpected token { in JSON at position 17 // 較舊的措辭
// Python(類比)
json.decoder.JSONDecodeError: Extra data: line 1 column 18 (char 17)報的位置指向有效值之後的第一個字元 —— 「多餘資料」就從那裡開始。
為什麼會這樣
原因 1 —— 兩個 JSON 值接在一起
// ❌ 兩個物件首尾相接 —— 一個有效值,然後還有更多
{"id":1}{"id":2}
// ^ 第 8 位置:JSON 資料後出現了非空白
// ✅ 用陣列包起來
[{"id":1},{"id":2}]原因 2 —— NDJSON / JSON Lines 被當成一團解析
日誌檔案和串流 API 經常會發出一行一 個 JSON 物件(NDJSON)。JSON.parse() 只讀第一行的值,遇到下一行就掛了。
// ❌ 對整個檔案做 JSON.parse
{"event":"login"}
{"event":"logout"}
// ✅ 一行一行解析
const rows = text
.split('\n')
.filter(Boolean)
.map((line) => JSON.parse(line));原因 3 —— 尾巴上的垃圾或重複的回應
// ❌ 多餘文字、被複製了一遍的 payload,或尾端分號
{"ok":true};
{"ok":true} // 代理伺服器追加的偵錯行
extraJSON-RPC 與其他帶分幀的串流
如果你正在消費一個協定 —— stdio 上的 JSON-RPC、Language Server Protocol (LSP)、Debug Adapter Protocol —— 多個 JSON 訊息按設計就是從同一條頻道流過去的。它們各自帶了一層分幀層,告訴你下一條訊息有多長,正是為了讓你不用在同一個緩衝區裡解析兩個值:
Content-Length: 87\r\n
\r\n
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{...}}Content-Length: 42\r\n
\r\n
{"jsonrpc":"2.0","id":1,"result":{...}} 規則是:讀 Content-Length 標頭,然後讀剛好那麼多位元組,再解析一個 JSON 值,然後迴圈。如果你把整條頻道一口吃下再一次解析,就會撞上「unexpected non-whitespace character after JSON data」,因為裡面有很多個值。
對 NDJSON 來說,對應的規則是「按 \n 切,逐行解析」。共通主題是:一串 JSON 訊息總得有一層分幀;裸接不是合法的 JSON。
怎麼修 —— 一步一步
- 跳到報錯位置 —— 從那裡開始的所有內容就是「多餘資料」。看看緊接在第一個完整值後面的是什麼。
- 有多個值? 如果你本來想做清單,用
[ … ]陣列把它們包起來,用逗號分隔。 - NDJSON / JSON Lines? 按換行切,逐行解析 —— 不要一次解析整個檔案。
- 尾巴上有垃圾? 解析前去掉多餘字元(分號、重複的 payload、偵錯輸出)。
- 正在做串流? 確認你沒有把多個回應拼到同一個緩衝區再解析。
常見問題
「unexpected non-whitespace character after JSON data」是什麼意思?
解析器讀到一個有效的 JSON 值,然後在後面發現了更多內容。JSON 只允許一個頂層值,因此後續字元是非法的。
怎麼解析多個 JSON 物件?
如果是接在一起的,用陣列包起來。如果是一行一個(NDJSON / JSON Lines),按換行切,再單獨 JSON.parse() 每一行。
這跟「Unexpected end of JSON input」是同一回事嗎?
它們相反。本錯誤表示資料太多(完整值後面還有東西);「Unexpected end of JSON input」 表示資料太少(值被截斷)。
立刻修復
- JSON Fix —— 在瀏覽器裡找出末尾多餘資料並清掉
- Unexpected End of JSON Input —— 相反的「資料太少」錯誤
- 如何修復 JSON.parse 的 Unexpected Token 錯誤 —— 每一種 token 變體
- 修復「[object Object] is not valid JSON」 —— 完整的語法錯誤參考