极简工具箱

免费在线工具 · 本地计算 · 无需上传

UTF-8 BOM 是什么:为什么它会让 JSON 解析失败

代码看着完全正确,JSON 解析却报「Unexpected token」,把文件用十六进制打开,开头多了三个字节 `EF BB BF`——这就是 BOM,一个看不见却能让程序崩掉的东西。

广告位(百度联盟)

一、BOM 是什么

BOM(Byte Order Mark)是文件开头的一个特殊标记,UTF-8 的 BOM 是三个字节:

EF BB BF

它原本的用途是标识字节序(大端/小端),但 UTF-8 本身没有字节序问题,所以这个标记在 UTF-8 里纯粹是「我是一个 UTF-8 文件」的提示。问题在于:它不是内容,但很多解析器会把它当内容读进去。

二、它会造成哪些具体故障

场景现象
JSON 解析JSON.parse 报 Unexpected token,位置在第 1 行第 1 列
PHP / 模板输出页面顶部多出空白,headers already sent 警告
配置文件第一个键名变成 key,读取时找不到
CSV第一个表头多一个不可见字符,字段映射失败
Shell 脚本#!/bin/bash 前有 BOM,报 bad interpreter
合并文件多个文件拼接后中间冒出乱码字符

这些故障的共同点是报错位置和真实原因完全不匹配,所以特别耗时间。

三、为什么 Excel 反而需要它

Windows 版 Excel 打开 CSV 时靠 BOM 判断「这是 UTF-8」。没有 BOM,它就按本地 ANSI(简体中文是 GBK)解析,中文变乱码。所以:

这两个需求是冲突的,所以同一份数据不要既当配置文件又当 Excel 表格,导出两份更省事。

四、怎么检测

五、怎么去除

# Linux / macOS:去掉开头的 BOM
sed -i '1s/^\xEF\xBB\xBF//' file.txt

# 或用 dos2unix(会顺带处理 BOM)
dos2unix file.txt
# Python:用 utf-8-sig 读,会自动吞掉 BOM
text = open('a.json', encoding='utf-8-sig').read()

# 写出时不带 BOM
open('b.json', 'w', encoding='utf-8').write(text)
// JS:读进来后手动去掉
const clean = str.replace(/^\uFEFF/, '');

注意别用「在编辑器里删掉第一个字符」这种办法——BOM 常常不可见,手动删容易删掉真正的第一个字符。

六、怎么从源头避免

七、和乱码的区别

BOM 造成的是「多了一个字符」,不是「一串乱码」。如果整个文件中文都是乱码,那是编码不一致(见 中文乱码排查);如果只有第一行第一列出现莫名其妙的错误,先查 BOM。

拿不准某个文件开头是什么字节,可以用 Unicode 转换工具 查看码点,或者直接丢进 JSON 格式化校验——如果它报第 1 行第 1 列错误而内容看起来完全正常,八成就是 BOM。

小结

UTF-8 BOM = 文件开头的 EF BB BF,对程序是垃圾、对 Excel 是信号。给机器读的文件一律无 BOM,给 Excel 看的 CSV 才加;报错位置在第一行第一列且内容正常时,先查 BOM。

本文相关工具(本地计算,无需上传)

更多使用教程