📚 EVEDAYS Guide Book
[开发者工具]•6 分钟阅读

JSON 解析失败的五个原因,以及大数精度陷阱

1. JSON 比想象中严格


JSON 看起来像 JavaScript 对象字面量,但语法窄得多。它由 RFC 8259 与 ECMA-404 定义,许多在 JavaScript 中合法的写法在 JSON 中并不合法。

2. 解析失败的五个原因


① 尾随逗号
{"a": 1, "b": 2,} —— 最后一项后的逗号会报错。JavaScript 允许,JSON 不允许。

② 键没有双引号
{a: 1} —— 键必须是用双引号括起的字符串。

③ 使用单引号
{'a': 'b'} —— JSON 只承认双引号。

④ 注释
// 说明 与 /* */ 都不属于 JSON 标准。配置文件若需注释,须使用 JSONC 或 JSON5 等扩展格式。

⑤ 特殊值
NaN、Infinity、undefined 不存在于 JSON。请用 null 或字符串表示缺失的数值。

此外,在字符串中直接换行同样是错误,必须转义为 \n。

3. 如何解读错误位置


解析器通常会提示类似 “position 42” 的位置,但真正的原因往往在更靠前的位置。 少写一个引号,解析器会把后面的内容都当作字符串的一部分,直到很远处才失败。

把文档放进格式化工具展开结构,更容易用肉眼找到嵌套错位之处。

4. 大数精度陷阱


这不是语法错误,而是数值被悄悄改变,因此更危险。

JavaScript 的数字为双精度浮点数,能精确表示的整数上限为:

Number.MAX_SAFE_INTEGER = 9007199254740991

用 JSON.parse 读取更大的整数时,数值会被静默改变。例如 12345678901234567890 解析后变成 12345678901234567000,既无报错也无警告。

何时会出问题
  • Snowflake 式的 64 位 ID(Twitter、Discord 等)

  • 数据库中的 BIGINT 主键

  • 以最小货币单位表示的大额金额


  • 应对方法
    标准做法是由服务端将此类值序列化为字符串:{"id": "12345678901234567890"}。若客户端必须按数字处理,可使用 BigInt 配合自定义 reviver。

    5. JSON 的各种变体


    | 格式 | 差异 | 用途 |
    |---|---|---|
    | JSON | 标准 | API 响应、数据交换 |
    | JSONC | 允许注释 | VS Code 配置等 |
    | JSON5 | 允许注释、尾随逗号、单引号 | 人工编写的配置文件 |
    | NDJSON / JSON Lines | 每行一个 JSON | 日志、流式处理、大批量处理 |

    不要因为配置文件能用 JSONC,就把它用于 API 响应,标准解析器会拒绝。

    6. 安全提示


    至今仍能看到用 eval() 处理 JSON 字符串的代码。切勿如此。 不可信输入中若含代码将被直接执行。JSON.parse 是安全的。

    7. 工具


    EVEDAYS JSON 格式化工具 在浏览器内完成校验与美化。API 响应中常含个人信息或令牌,选择不向外发送的工具更为稳妥。

    8. 出处


  • RFC 8259 — JSON 数据交换格式

  • ECMA-404 — JSON 数据交换语法

  • MDN — JSON.parse()
  • EVEDAYS Editorial Team