JSON 详解:现代 Web 数据交换的标准
什么是 JSON?
JSON(JavaScript Object Notation,JavaScript 对象表示法)是一种轻量级的数据交换格式。它基于 ECMAScript(欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
JSON 的核心特性
- 轻量级: 相比 XML,JSON 格式更加简洁,数据体积更小,网络传输速度更快。
- 语言无关: 虽然源于 JavaScript,但目前几乎所有现代编程语言(Python, Java, C#, PHP, Go 等)都支持 JSON。
- 自我描述性: JSON 结构清晰,易于理解和阅读。
- 易于解析: 各种语言都有内置或第三方库可以轻松解析和生成 JSON 数据。
JSON 语法规则
JSON 语法是 JavaScript 对象表示法语法的子集:
代码示例
{
"employees": [
{
"firstName": "Bill",
"lastName": "Gates"
},
{
"firstName": "George",
"lastName": "Bush"
},
{
"firstName": "Thomas",
"lastName": "Carter"
}
]
}JSON 数据类型
字符串 (String)
必须用双引号包围。
"name": "John"数字 (Number)
整数或浮点数。
"age": 30对象 (Object)
用于包含键值对。
"address": {...}数组 (Array)
有序的值的集合。
"hobbies": [...]布尔值 (Boolean)
true 或 false。
"isStudent": trueNull
表示空值。
"middleName": nullJSON vs XML
| 特性 | JSON | XML |
|---|---|---|
| 可读性 | 结构简洁,易读 | 标签繁琐,相对较难读 |
| 解析速度 | 快,原生支持好 | 相对较慢,需 XML 解析器 |
| 数据体积 | 小,传输快 | 大,传输占用更多带宽 |
| 类型支持 | 支持数组、对象等 | 结构化强,但类型表达不如 JSON 直观 |
XML 简介与使用
XML(eXtensible Markup Language,可扩展标记语言)是一种用于标记电子文件使其具有结构性的标记语言。与 JSON 不同,XML 使用自定义标签来描述数据结构,是许多企业级系统和 SOAP Web 服务的基础数据格式。
XML 的核心特性
- 自描述性:标签名称由开发者自定义,使文档语义清晰。
- 严格的结构验证:支持 DTD 和 XML Schema 定义文档结构。
- 命名空间支持:通过 xmlns 避免不同来源的元素名冲突。
- XSLT 转换:可使用样式表将 XML 转换为 HTML、PDF 等格式。
XML 与 JSON 的常见转换错误
在实际开发中,XML 和 JSON 之间的转换是最容易出错的环节之一。以下是一些典型陷阱:
- 属性丢失:XML 元素的属性(如 <item id="123">)在转换为 JSON 时需明确映射规则,否则容易丢失。
- 命名空间处理:XML 中的 xmlns 前缀在 JSON 中没有直接对应,需手动处理。
- 数组识别:XML 中重复的同名元素应映射为 JSON 数组,但自动转换工具可能只保留最后一个元素。
- 字符编码:XML 默认 UTF-8,但 CDATA 区块中的特殊字符(如 & < >)需额外处理。
XML 示例
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
</book>
</catalog>JSON Schema:数据结构的契约
JSON Schema 是一种声明性语言,用于定义和校验 JSON 数据的结构。它相当于 JSON 文档的「类型系统」,帮助前后端协作者对数据结构达成一致理解。
一个简单的 Schema 示例——定义用户对象必须包含 name(字符串)和 age(数字,最小 0):
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer", "minimum": 0}
},
"required": ["name", "age"]
}Schema 在实际项目中的价值:
- API 文档自动生成:通过 Schema 可自动生成 API 文档和交互式测试界面(如 Swagger/OpenAPI)。
- 前置校验:数据存入数据库前,先用 Schema 校验,避免脏数据进入系统。
- 前后端协作:前后端共享同一份 Schema 文件,减少沟通成本和联调时间。
- 测试用例生成:根据 Schema 自动生成合法和非法的测试数据。
JSON 的高级使用模式
JSON 引用与去重
大规模 JSON 中常有重复数据。使用 引用机制(JSON Schema 标准)可以避免冗余:
{
"definitions": {
"address": {
"type": "object",
"properties": {
"street": {"type": "string"},
"city": {"type": "string"}
}
}
},
"user": {
"homeAddress": {"$ref": "#/definitions/address"},
"workAddress": {"$ref": "#/definitions/address"}
}
}注意:JSON 标准本身不处理 ,这依赖具体的工具或库实现。
JSONPath:JSON 的查询语言
JSONPath 之于 JSON,如同 XPath 之于 XML。它用简洁的路径表达式从复杂 JSON 中提取数据:
$.store.book[*].author— 提取所有书的作者$..price— 提取任意嵌套层级中所有的 price 字段$.store.book[?(@.price < 10)]— 过滤价格小于 10 的书$.store.book[-1]— 获取最后一本书
JSONPath 在 API 测试、日志分析、数据处理脚本中广泛使用。
JSON 流式处理(Streaming)
当 JSON 文件大到无法一次性载入内存时(例如数百 MB 的日志文件),流式解析是最佳方案。解析器逐字符读取,遇到完整的 JSON 对象就触发回调,无需将整个文件读入内存。
Node.js 生态中 JSONStream、clarinet 等库提供流式解析能力。Python 的 ijson 库也支持类似操作。
在 yyjson.top 中,格式化功能虽然基于浏览器内存,但对于 50MB 以内的 JSON 文件仍能稳定处理,前提是关闭其他占用内存的标签页。
JSON 的安全注意事项
- JSON 注入攻击:如果直接将用户输入的 JSON 值拼接到 SQL 语句或 HTML 中而不做转义,可能导致注入。始终使用参数化查询和内容安全策略(CSP)。
- JSONP 劫持:历史遗留的 JSONP 接口可能被恶意站点通过 script 标签跨域请求。现代应用应使用 CORS + 自定义请求头替代 JSONP。
- 大数精度丢失:JavaScript 的 Number 类型最大安全整数为 2^53-1。超过此范围的整数(如 64 位 ID)应在 JSON 中以字符串形式传递,避免解析时精度丢失。
- 原型污染:某些 JSON 解析库在处理
__proto__或constructor.prototype键时可能污染对象原型。选择成熟的解析库可避免此问题。 - 拒绝服务(DoS):嵌套层级极深(如一万层)或数据量极大的 JSON 可能耗尽解析器资源。对不可信来源的 JSON 设置最大深度限制(如 100 层)。
常见应用场景
- Web API 接口: 前后端分离架构中,数据交互的首选格式。
- 配置文件: 如 VS Code 的 settings.json, package.json 等。
- NoSQL 数据库: MongoDB 等数据库直接存储类 JSON 格式文档。
- 日志记录: 结构化日志存储,便于后续分析。
需要格式化 JSON 数据?
使用在线 JSON 格式化工具