JSON 报错却看不到错在哪?可能是 BOM

有一种诡异的 JSON 报错:文件用肉眼看完全正常,但 JSON.parse 偏偏报 Unexpected token at position 0。这种「看不见的错误」,元凶往往是文件开头的 BOM 隐藏字符。

BOM 是什么

BOM(Byte Order Mark,字节序标记)是一个藏在文件最开头的不可见字符 U+FEFF。它的本意是标记文件的字节序,但 UTF-8 编码根本不需要它。问题是:Windows 上一些旧版编辑器(尤其是记事本)保存 UTF-8 文件时,会偷偷在开头加一个 BOM。

这个字符肉眼看不见,但会被 JSON 解析器读到,于是报错位置是 position 0——也就是最开头那个「看不见」的字符。

典型的报错样子

JSON.parse(bomJson);
// SyntaxError: Unexpected token  in JSON at position 0

注意 token 后面是空的,不是 token , 或 token {,因为那个字符本身就是不可见的。

如何确认是不是 BOM

看报错位置:如果是 position 0,且文件看起来明明合法,几乎可以断定是 BOM。也可以用代码检测:

const hasBOM = str.charCodeAt(0) === 0xFEFF;
console.log(hasBOM ? '有 BOM' : '无 BOM');

如何去除 BOM

方法一:编辑器另存为「UTF-8 无 BOM」

用 VSCode、Sublime、Notepad++ 等编辑器打开文件,另存为时把编码选成 UTF-8(无 BOM),保存即可。这是最推荐的做法。

方法二:代码里去掉

const clean = str.replace(/^\uFEFF/, '');
JSON.parse(clean);

如果还是不确定错在哪

如果报错位置不是 0,或者你无法确定是不是 BOM,直接把内容粘进 JSON 在线校验工具——它会精确定位到错误所在的行和列,并给出原因,比手动排查快得多。

延伸阅读

常见问题

为什么 JSON 看起来正常却报 Unexpected token at position 0?

多半是文件开头有 BOM(U+FEFF)隐藏字符,Windows 记事本等旧编辑器保存 UTF-8 文件时会偷偷加它,肉眼看不见但解析器能读到。

怎么判断 JSON 是不是有 BOM?

看报错位置:如果是 position 0 且文件看起来合法,几乎可以断定是 BOM;也可以用 charCodeAt(0) === 0xFEFF 检测。

如何去除 JSON 的 BOM?

最推荐用编辑器另存为 UTF-8 无 BOM;也可以在代码里用 replace(/^\uFEFF/, '') 去掉。