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": true

Null

表示空值。

"middleName": null

JSON vs XML

特性JSONXML
可读性结构简洁,易读标签繁琐,相对较难读
解析速度快,原生支持好相对较慢,需 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 生态中 JSONStreamclarinet 等库提供流式解析能力。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 层)。

常见应用场景

  1. Web API 接口: 前后端分离架构中,数据交互的首选格式。
  2. 配置文件: 如 VS Code 的 settings.json, package.json 等。
  3. NoSQL 数据库: MongoDB 等数据库直接存储类 JSON 格式文档。
  4. 日志记录: 结构化日志存储,便于后续分析。

需要格式化 JSON 数据?

使用在线 JSON 格式化工具