教程 · 入门

JSON 常见语法错误排查

浏览器里 JSON.parse 一失败,控制台就丢一句 Unexpected token。这条信息经常不准,真正的问题可能在上一行。下面按出现频率把坑列出来,每条都给能过、不能过的对照。你可以整段贴进 HiJSON,看它标在哪一行。

先分清:JS 对象字面量和 JSON

很多人从代码里复制一段对象,期望它「差不多就是 JSON」。差得还挺多。JavaScript 允许尾逗号、单引号、未加引号的键、注释、undefined。标准 JSON 这些都不认。编辑器里能跑的对象,粘到接口文档或配置文件里就会炸。

JSON 只承认六种值:对象、数组、字符串、数字、true/falsenull。字符串必须双引号。键必须是字符串。

1. 最后一个元素后面多了逗号

从 TypeScript 或 ESLint 配过 trailingComma 的项目拷出来,最容易带上这个。

{
  "id": 12,
  "name": "order",
}

改成:

{
  "id": 12,
  "name": "order"
}

数组同样不行:[1, 2, 3,]。有些宽松解析器(JSON5、部分 YAML 转 JSON 工具)会吞掉尾逗号,你这边过了,同事用标准库一解析又挂。联调时以 RFC 8259 为准。

2. 单引号、未加引号的键

{'name': 'test'}
{name: "test"}

两行都非法。正确写法是 {"name": "test"}。Python 的 dict 打印、Mongo shell、部分日志框架会吐单引号,需要先替换再解析,不要手改几百行,容易漏。

3. 注释

VS Code 的 settings.json 实际是 JSONC,允许 ///* */。标准 JSON 没有注释。从配置文件抠一段去当 API body,经常卡在注释上。

真要给人看结构,把说明写在旁边的文档里,或者用 JSON Schema 的 description 字段。不要在 payload 里夹注释碰运气。

4. NaN、Infinity、undefined

JSON.stringify({ a: NaN, b: Infinity, c: undefined }) 在浏览器里会变成 {"a":null,"b":null}c 直接丢掉。你以为发出去了,对端收到的是 null 或字段消失。

反过来,有的服务端(早期 PHP、某些日志)会写出 {"score": NaN}。这不是合法 JSON。约定用 null,或者改成字符串 "NaN" 并在文档里写清楚。

5. 字符串里的换行和引号没转义

{
  "msg": "第一行
第二行"
}

JSON 字符串不能直接折行,要写成 "第一行\\n第二行"。内部双引号写成 \\",反斜杠写成 \\\\。从 Word、聊天软件粘过来的文本,有时带着弯引号 “”,解析器只认 "

6. 重复键

{
  "status": "ok",
  "status": "fail"
}

规范不鼓励重复键,多数解析器静默留最后一个。表面上「能 parse」,两边读到的值可能不一样。合并配置、手写 mock 时特别容易发生。树视图里如果同一层出现两个同名键,先当事故查,不要当特性用。

7. 文件开头的 BOM

Windows 记事本另存为 UTF-8 时可能带 BOM。第一个字符是不可见的 U+FEFF,报错常写 Unexpected token 在 position 0。用十六进制看文件头,或在编辑器里「以 UTF-8 无 BOM 保存」。

8. 把好几个对象糊在一起

日志里常见一次贴三行对象,中间没有包成数组:

{"id":1}
{"id":2}

这叫 JSON Lines,不是一个 JSON 文档。要么改成 [{...},{...}],要么按行拆开。HiJSON 支持拖入 .jsonl,详见 JSON Lines 与日志分析

建议的排查顺序

  1. 看报错列号。多数实现给的是「解析器放弃的位置」,真正语法错误常常在它前面几个字符。
  2. 先查尾逗号和单引号,这两项占日常失败的一大半。
  3. 还有问题就搜 //NaNundefined、中文弯引号。
  4. 仍然过不了,把原文存成文件,看编码和 BOM。
  5. 确认它是不是 JSONL、JSONP(callback({...}))或 YAML 误贴。

HiJSON 解析失败会在输入框下方给出位置。修好再点解析,或 Ctrl+Enter。格式化按钮只对已经合法的文本有意义,非法文本先过语法再谈缩进,见 格式化指南

常见问题

Postman 里能看,粘到这里报错?
有的客户端展示层会「美化」或容忍尾逗号。复制时选 raw body,不要从预览面板抄。
数字特别大,解析后变了?
这不一定是语法错误。JavaScript 安全整数到 2^53-1,再大的订单号建议当字符串传。语法过了但值漂了,属于语言限制,见 多语言解析

相关教程

把报错贴进来看位置

数据只在浏览器里解析,不会上传。

打开 HiJSON →