JSON(JavaScript Object Notation,JavaScript 对象表示法)是一种轻量级的文本格式,用于存储和交换结构化数据,由键值对组成的对象、有序数组以及少数几种值类型构成:字符串、数字、true、false 和 null。它易于人类阅读,又便于所有编程语言解析,因此成为 Web API 和许多配置文件的默认格式。JSON 的规则很严格:键和字符串必须使用双引号,不允许末尾逗号和注释。
- JSON 恰好有六种值:对象、数组、字符串、数字、布尔值(
true/false)和null。 - 键必须是用双引号括起来的字符串;单引号永远无效。
- 不允许末尾逗号、注释,也不允许
undefined、NaN或Infinity。 - 大多数“JSON 无效”的错误都来自缺少或多余的逗号、用错的引号,或字符串中未转义的字符。
- 先用严格的解析器校验语法,如有需要再用 JSON Schema 校验结构。
JSON 长什么样
JSON 源自 JavaScript 对象字面量的语法,但与具体语言无关。它定义在 RFC 8259 和 ECMA-404 标准中,json.org 上的一页摘要描述了完整的语法。一份典型的文档如下所示:
{
"id": 1042,
"name": "Ada Lovelace",
"email": "ada@example.com",
"active": true,
"score": 98.5,
"manager": null,
"roles": ["admin", "editor"],
"address": {
"city": "London",
"postcode": "N1 9GU"
}
}
元素之间的空白(空格、制表符和换行)会被忽略,因此同样的数据既可以写成一行,也可以用缩进展开。JSON 文档的顶层可以是任何值,不过 API 几乎总是使用对象或数组。
JSON 数据类型
| 类型 | 示例 | 规则 |
|---|---|---|
| 对象 | {"a": 1, "b": 2} | 花括号中的无序键值对集合。键是字符串;冒号分隔键和值;逗号分隔键值对。 |
| 数组 | [1, "two", false] | 方括号中的有序值列表,以逗号分隔。值的类型可以混合。 |
| 字符串 | "caf\u00e9 \"quoted\"" | 只能使用双引号。反斜杠转义:\" \\ \/ \b \f \n \r \t 和 \uXXXX。字符串内部不允许出现原始的换行和制表符。 |
| 数字 | -12、3.14、6.02e23 | 只能是十进制。不能有前导 +,不能有前导零(07),不能是十六进制,也不能是 NaN 或 Infinity。小数点两侧都必须有数字。 |
| 布尔值 | true、false | 小写,不加引号。 |
| 空值 | null | 小写,不加引号。表示空值或未知值。 |
JSON 没有日期类型。日期通常写成 ISO 8601 格式的字符串,例如 "2026-10-13T09:30:00Z",或者写成数字形式的 Unix 时间戳;我们的 Unix时间戳转换器可以在两者之间转换。
数字与精度
JSON 标准并不限制数字的大小或精度,但读取它的程序会有限制。JavaScript 以 64 位浮点数存储数字,因此大于 9,007,199,254,740,991(253 − 1)的整数可能会在不知不觉中丢失精度。对于很大的 ID,许多 API 会把它们作为字符串发送,例如 "id": "1234567890123456789"。
最容易出错的规则
JSON 看起来像 JavaScript、Python 字典和 YAML,这正是人们不小心写出无效 JSON 的原因。以下规则在标准 JSON 中没有例外:
- 键必须是用双引号括起来的字符串。
{name: "Ada"}在 JavaScript 中有效,但不是有效的 JSON;请写成{"name": "Ada"}。 - 只能使用双引号。
'Ada'不是 JSON 字符串。 - 不允许末尾逗号。
[1, 2, 3,]和{"a": 1,}都无效。 - 不允许注释。
// ...和/* ... */都不行。 - 字面值必须小写。
True、FALSE和None(Python 的写法)无效;请使用true、false和null。 - 没有
undefined、函数或特殊数字。这些在 JavaScript 中存在,但在 JSON 中没有对应的写法。 - 键应当唯一。标准规定对象内的名称应当唯一;出现重复时,各解析器的行为不一,许多解析器会悄悄地只保留最后一个。
有些工具接受宽松的变体。VS Code 的 settings.json 和 TypeScript 的 tsconfig.json 等文件使用允许注释的解析器读取(通常称为 JSONC),而 JSON5 则允许注释、单引号和末尾逗号。它们是独立的格式:标准 JSON 解析器(包括您的 API 客户端或服务器所使用的解析器)会拒绝它们。
常见 JSON 错误及修复方法
不同解析器的错误措辞各不相同。下表列出了您在 Python 的 json 模块或浏览器的 JSON.parse 中会看到的消息类型、它通常意味着什么,以及修复方法。报告的位置往往在真正出错处的稍后,所以也请检查它前面的那个字符。
| 问题 | 典型错误信息 | 修复方法 |
|---|---|---|
末尾逗号:{"a": 1,} | “Expecting property name enclosed in double quotes”或“Unexpected token }” | 删除对象或数组最后一项后面的逗号。 |
键没有引号或使用单引号:{a: 1}、{'a': 1} | “Expecting property name enclosed in double quotes”或“Expected double-quoted property name” | 给每个键加上双引号。 |
字符串值使用单引号:{"a": 'x'} | “Expecting value”或“Unexpected token '” | 改用双引号,并把其中的双引号转义为 \"。 |
| 各项之间缺少逗号 | “Expecting ',' delimiter”或“Expected ',' or '}' after property value” | 在报错行的两个值或键值对之间添加逗号。 |
| 文件中有注释 | “Expecting value”或“Unexpected token /” | 删除注释,或把说明移到 "_comment" 这样的数据字段中。 |
Python 或 JavaScript 字面值:True、None、undefined、NaN | “Expecting value”或“Unexpected token” | 使用 true、false 或 null;请用真正的 JSON 库序列化数据,而不是直接打印。 |
| 字符串中有原始的换行或制表符 | “Invalid control character”或“Bad control character in string literal” | 替换为 \n 或 \t。 |
未转义的反斜杠,例如 Windows 路径 "C:\new" | “Invalid \escape”或“Bad escaped character” | 把反斜杠写成两个:"C:\\new"。 |
| 缺少右括号或右引号 | “Unterminated string”或“Unexpected end of JSON input” | 检查每个 {、[ 和 " 是否都已闭合;格式化工具的缩进会让缺口一目了然。 |
| 两个文档紧挨在一起,或结尾之后还有文本 | “Extra data”或“Unexpected non-whitespace character after JSON” | 把多个对象包在一个数组里,或把输入按 JSON Lines(每行一个文档)处理。 |
| 空响应或 HTML 错误页被当作 JSON 解析 | “Expecting value: line 1 column 1”或“Unexpected token <” | 检查 HTTP 状态码和响应正文;服务器返回的不是 JSON。 |
最后一行是实际中最常见的情况之一:代码对以 <!DOCTYPE html> 开头的错误页调用 JSON.parse 或 response.json(),于是 < 被报告为意外的标记。
JSON、YAML 与 XML 的对比
| JSON | YAML | XML | |
|---|---|---|---|
| 结构 | 花括号和方括号 | 缩进 | 开始标签和结束标签 |
| 注释 | 不支持 | 支持(#) | 支持(<!-- -->) |
| 数据类型 | 字符串、数字、布尔值、null、对象、数组 | 类似,另有日期等类型,具体取决于解析器 | 除非由 schema 指定类型,否则一切都是文本 |
| 属性和混合内容 | 不支持 | 不支持 | 支持 |
| 冗长程度 | 紧凑 | 读起来最简洁 | 最冗长 |
| 典型用途 | Web API、浏览器存储、包清单、日志 | 配置:Kubernetes、Docker Compose、CI 流水线 | 文档、SOAP、RSS 和 Atom、站点地图、办公文件格式 |
| 主要陷阱 | 严格的引号和逗号规则 | 对空白敏感;某些不带引号的值会被意外解释 | 冗长;命名空间和实体增加了复杂性 |
YAML 1.2 的设计使得 JSON 文档在极少数边缘情况之外同样是有效的 YAML,因此两者之间的转换很简单。我们的 JSON ↔ YAML转换器支持双向转换,YAML格式化与校验和 XML格式化与校验可校验另外两种格式,而 CSV ↔ JSON转换器则能把电子表格导出的数据变成对象数组。
美化与压缩
由于空白无关紧要,同样的 JSON 可以按适合人读或适合机器读的方式排版:
- 美化后的 JSON 会添加换行和缩进(通常是两个或四个空格),让嵌套层级一目了然。适用于配置文件、文档和调试。
- 压缩后的 JSON 会去掉所有可选的空白,使数据更小。适用于通过网络发送或大批量存储的数据;HTTP 压缩同样能减小体积,因此节省的空间往往有限。
{"name":"Ada","roles":["admin","editor"],"active":true}
大多数语言两者都能做到。在 JavaScript 中,JSON.stringify(data, null, 2) 以两个空格缩进美化输出,JSON.stringify(data) 则进行压缩。在 Python 中,json.dumps(data, indent=2) 用于美化,json.dumps(data, separators=(",", ":")) 则给出最紧凑的输出。
如何校验 JSON
校验 JSON 分为两个层面:它在语法上是不是有效的 JSON,以及它是否具备您的应用所期望的结构?
- 用严格的解析器检查语法。把文本粘贴到我们的 JSON格式化与校验中,它会报告第一个错误所在的行和列,并且在您的浏览器中运行。在命令行中,
python3 -m json.tool data.json或jq . data.json会输出格式化后的文档或错误信息。 - 逐个修复错误。解析器遇到第一个问题就会停止,所以每修复一处后请重新运行,直到成功为止。
- 检查结构。通过代码或 JSON Schema 校验器,确认必需的字段存在且类型正确。
- 检查编码。系统之间交换的 JSON 应当使用 UTF-8。以其他编码保存的文件,遇到非英文文本时可能出现乱码或错误。
JSON Schema 简介
JSON Schema 是一套本身用 JSON 编写的词汇,用来描述有效文档应当是什么样子:哪些属性是必需的、每个属性必须是什么类型、允许的取值、字符串模式、数值范围等等。大多数语言都有对应的校验器,OpenAPI 等 API 描述格式也使用 JSON Schema 来描述请求和响应正文。规范发布在 json-schema.org。一个小例子:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["id", "email"],
"properties": {
"id": { "type": "integer", "minimum": 1 },
"email": { "type": "string", "format": "email" },
"roles": { "type": "array", "items": { "type": "string" } }
}
}
缺少 email 或 id 为字符串的文档仍是有效的 JSON,但无法通过这个 schema。请注意,许多校验器把 format 视为注解,除非另行配置,否则不会强制执行。
常见问题
JSON 可以有注释吗?
不可以。标准 JSON 不允许任何形式的注释。有些工具接受允许注释的 JSONC 或 JSON5,但供其他程序读取的文件应当坚持使用纯 JSON。如果需要写说明,可以添加 "_comment" 这样的字段。
为什么 JSON 不允许末尾逗号?
该语法被有意保持得极其精简,只是没有包含末尾逗号。许多 JavaScript 引擎和其他语言在自己的语法中接受末尾逗号,所以它们常常被误写进手写的 JSON 里。
JSON 和 JavaScript 对象有什么区别?
JSON 是一种文本格式;JavaScript 对象是内存中的数据结构。JSON 的语法是 JavaScript 字面量语法中更严格的子集。您可以使用 JSON.parse 和 JSON.stringify 在两者之间转换。
“Unexpected token < in JSON at position 0”是什么意思?
被解析的文本以 < 开头,这几乎总是说明您收到的是 HTML(例如错误页或登录页),而不是 JSON。请检查请求的 URL、HTTP 状态码和原始响应正文。
JSON 对象中键的顺序会被保留吗?
标准把对象视为无序的,所以您不应依赖键的顺序。实际上,大多数现代解析器会保留读取时的顺序,但 JSON 唯一保证的顺序是数组的顺序。
JSON 使用什么文件扩展名和 MIME 类型?
文件使用 .json 扩展名,媒体类型是 application/json,已在 RFC 8259 中注册。
评论
登录后即可为此工具评分。
分享技巧、提出问题,或说说这个工具对您是否有用。
还没有评论,来分享您的使用体验吧。