SyntaxError: Unexpected token 'u', "undefined" is not valid JSON(舊版引擎:Unexpected token u in JSON at position 0)幾乎總是代表你呼叫了 JSON.parse(undefined)。JavaScript 把 undefined 字串化成文字 "undefined",於是 parser 在開頭那個 u 上卡住。下面說明原因與如何修。
錯誤長什麼樣
// V8 (Chrome / Node / Edge)
SyntaxError: "undefined" is not valid JSON
SyntaxError: Unexpected token 'u', "undefined" is not valid JSON
SyntaxError: Unexpected token u in JSON at position 0 // 較舊的 V8
// Firefox
SyntaxError: JSON.parse: unexpected character at line 1 column 1
// Safari
SyntaxError: JSON Parse error: Unexpected identifier "undefined" 位置 0 的 u 就是字串 "undefined" 的第一個字母 —— parser 根本沒拿到真正的資料。
為什麼會這樣:你解析了 undefined
JSON.parse() 會先把它的引數強制轉成字串。傳進 undefined 它就會去解析字面文字 "undefined",而那不是合法 JSON。值是 undefined 通常因為:
- 一個變數或函式引數從來沒有被 賦值
- 一個物件屬性不存在(拼錯或物件結構不對):
obj.missing - 一個 async 值還沒就緒(在
await之前就解析了) - 把一個沒有
return的函式當成資料來源
壞掉的例子
const cached = localStorage.getItem('settings'); // key 不存在 → null,OK
const draft = window.appState?.draft; // 屬性不存在 → undefined
const data = JSON.parse(draft); // ❌ "undefined" is not valid JSON修好的例子
// 解析前先 guard
const data = draft ? JSON.parse(draft) : null;
// 或者一個安全的 helper
function safeParse(text, fallback = null) {
if (typeof text !== 'string' || text.trim() === '') return fallback;
try { return JSON.parse(text); } catch { return fallback; }
}
const data2 = safeParse(draft); 注意:JSON.parse(null) 不會 拋錯 —— 它回傳 null —— 而 localStorage.getItem() 對不存在的 key 回傳的是 null(不是 undefined)。所以一個 u 錯誤明確指向一個 undefined 值,而不是 storage 缺 key。
SyntaxError vs TypeError:為什麼你拿到的是 這個
一個細微但有用的細節:JSON.parse(undefined) 拋的是 SyntaxError,不是 TypeError。為什麼?因為規範規定 JSON.parse 會先把引數 強制轉成字串("undefined")再解析該字串。錯誤是「這段字串不是合法 JSON」,而不是「你傳了錯誤的型別」。這也是為什麼 JSON.parse(undefined) 與 JSON.parse("undefined") 會產生完全相同的「position 0」錯誤。
對比一下確實會做型別檢查的 API,例如 JSON.stringify(BigInt(1)) → TypeError,或 JSON.parse(Symbol()) → TypeError(Symbol 無法強制轉字串)。如果你要 catch parse 錯誤,用 err instanceof SyntaxError 來縮窄範圍,把 資料錯誤 與 引數錯誤 分開處理。
怎麼修 —— 一步步來
- 印出輸入:
console.log(typeof src, src)緊貼在 parse 之前。如果印出undefined,那就是元兇。 - 追蹤它應該被設定的位置 —— 一個未初始化的 state 欄位、缺失的引數、或者一個物件上根本不存在的屬性。
- 加上 guard(
if (src))或一個safeParsefallback,別讓缺失值跑到JSON.parse()。 - 如果是 async,請確定解析前先
await這個值。
常見問題
「Unexpected token u in JSON at position 0」是什麼意思?
你把 undefined 傳給了 JSON.parse()。它變成字串 "undefined",開頭的 u 不是合法的 JSON 起始字元。
它跟「token o」或「token <」錯誤是同一個嗎?
同一家族,不同值。u = undefined;token o = 一個物件被字串化成 [object Object];token < = 一個 HTML 回應。錯誤裡的那個字元告訴你實際傳進去的是什麼。
為什麼 JSON.parse(null) 不會丟同樣的錯?
"null" 是合法 JSON,所以 JSON.parse(null) 會回傳 null。只有 undefined(→ "undefined")會觸發這個 u 錯誤。
立刻修復
- JSON Fix —— 在瀏覽器裡驗證並修復 JSON
- 如何修復 JSON.parse 的 Unexpected Token 錯誤 —— 每種 token 變體
- Unexpected token o in JSON at position 1 —— 物件那個孿生錯誤
- 如何在 JavaScript 裡處理壞掉的 JSON —— safe-parse 模式