SyntaxError: Unexpected token 'u', "undefined" is not valid JSON(旧引擎:Unexpected token u in JSON at position 0)几乎总是意味着你调用了 JSON.parse(undefined)。JavaScript 把 undefined 字符串化成文本 "undefined",解析器就在开头那个 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" 的第一个字母 —— 解析器根本没拿到真实数据。
为什么会这样:你解析了 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 模式