同学们,今天咱们来聊聊一个在现代互联网世界无处不在的“通用语”——JSON。
你可能天天都在用它,但你真的了解它吗?它为什么这么流行?它有哪些规矩?又有哪些你可能不知道的“方方面面”?
别急,跟着我,咱们用最简洁明了的方式,把 JSON 彻底搞明白!
JSON 简明教程:数据世界的通用语
1. JSON 是什么?
JSON (JavaScript Object Notation),中文是“JavaScript 对象表示法”。听名字就知道它跟 JavaScript 有点亲戚关系。
简单来说,JSON 是一种轻量级的数据交换格式。它基于 JavaScript 的一个子集,但是!它独立于编程语言。这意味着,无论是 JavaScript、Python、Java、PHP、Go 还是其他任何语言,都能生成和解析 JSON 数据。
它的设计目的是为了实现人与机器都能轻松读写。它既有结构,又非常直观,是目前互联网上最流行的数据交换格式。
2. 为什么选择 JSON?
JSON 之所以能“一统天下”,是有它过人之处的:
-
轻量级: 相比 XML 等其他数据交换格式,JSON 的数据量更小,传输效率更高。
-
易于理解和编写: 它的语法非常简单直观,类似 JavaScript 对象字面量,人类阅读起来毫无障碍。
-
易于解析: 对于机器(特别是 JavaScript),解析 JSON 数据非常快速和简单。
-
语言无关性: 尽管起源于 JavaScript,但大多数主流编程语言都提供了内置的 JSON 解析和生成库。
-
用途广泛: 几乎所有需要数据交换的场景都能看到它的身影。
3. JSON 的基本结构与语法规则
JSON 数据主要由两种结构组成:
-
对象 (Object):
-
用大括号
{}表示。 -
表示一个无序的**“键值对”集合**。
-
每个键值对之间用逗号
,分隔。 -
键 (key) 必须是字符串,且必须使用双引号
""包裹。 -
值 (value) 可以是 JSON 支持的任意数据类型。
示例:
{ "name": "张三", "age": 30, "isStudent": false } -
-
数组 (Array):
-
用中括号
[]表示。 -
表示一个有序的值序列。
-
数组中的每个值之间用逗号
,分隔。 -
数组中的值可以是 JSON 支持的任意数据类型。
示例:
[ "苹果", "香蕉", "橙子" ] -
JSON 允许的数据类型
JSON 中的值,只能是以下六种数据类型:
-
字符串 (String): 必须用双引号
""包裹,支持 Unicode 字符和常见的转义字符(如\n,\t,\",\\等)。-
"Hello World" -
"这是一个带有\n换行的字符串"
-
-
数值 (Number): 整数或浮点数,不支持八进制、十六进制等。
-
100 -
3.14 -
-50
-
-
布尔值 (Boolean):
true或false。-
true -
false
-
-
空 (Null): 表示空值。
null
-
对象 (Object): 递归地包含其他 JSON 键值对。
{"city": "北京", "zip": "100000"}
-
数组 (Array): 递归地包含其他 JSON 值。
["red", "green", "blue"]
语法规则总结 (敲黑板!划重点!)
JSON 的语法非常严格,比 JavaScript 的对象字面量还要严格。记住这些“金科玉律”,避免踩坑:
-
键 (Key) 必须是字符串,且必须用双引号
""包裹。-
✅
"name" -
❌
name(这是 JavaScript 对象字面量可以,JSON 不行) -
❌
'name'(单引号不行)
-
-
字符串 (String) 的值必须用双引号
""包裹。-
✅
"hello" -
❌
'hello'(单引号不行)
-
-
键和值之间用冒号
:分隔。 -
键值对之间(对象中)或值之间(数组中)用逗号
,分隔。 -
最后一个键值对或值后面不能有多余的逗号 (Trailing Comma)。
-
✅
{"a": 1, "b": 2} -
❌
{"a": 1, "b": 2,}(这是 JavaScript 对象字面量可以,JSON 不行)
-
-
JSON 中不允许有注释 (
//或/* */)。 -
JSON 中不允许有函数、日期对象、
undefined、NaN等 JavaScript 特有的数据类型。 (它们在序列化时会被忽略或转换为null)
一个更复杂的 JSON 示例:
{
"book": {
"title": "JSON 权威指南",
"author": "JSON 大师",
"publishedYear": 2023,
"isAvailable": true,
"genres": ["编程", "数据交换", "网络"],
"details": {
"pages": 300,
"language": "中文"
},
"borrower": null
},
"libraryBranch": "中心图书馆",
"stock": [
{
"bookId": "B001",
"quantity": 5
},
{
"bookId": "B002",
"quantity": 2
}
]
}
4. JSON 的常见用途
JSON 凭借其简洁和通用性,在现代 Web 开发和数据处理中几乎无处不在:
-
Web API 数据传输: 这是 JSON 最主要的应用场景。服务器(后端)和客户端(前端、移动 App)之间通过 HTTP 请求交换数据,通常都是 JSON 格式。
-
配置文件: 许多应用程序和工具使用 JSON 作为其配置文件的格式,例如
package.json(Node.js 项目配置),tsconfig.json(TypeScript 配置)。 -
数据存储: 某些 NoSQL 数据库(如 MongoDB)直接使用 BSON (Binary JSON) 格式存储数据。
-
日志记录: 结构化日志通常采用 JSON 格式,便于日志分析工具处理。
-
数据序列化/反序列化: 将编程语言中的对象转换为字符串进行传输或存储,再将字符串转换回对象。
5. 如何在编程语言中使用 JSON
大多数主流编程语言都提供了处理 JSON 的内置方法或标准库。
JavaScript (JSON 的“老家”)
在 JavaScript 中,JSON 对象是内置的,提供了两个核心方法:
-
JSON.parse():将 JSON 字符串转换为 JavaScript 对象。- 当你的前端收到服务器返回的 JSON 字符串时,就需要用它来解析成你可以在 JS 里操作的对象。
const jsonString = '{"name": "小明", "age": 25, "city": "上海"}'; const jsObject = JSON.parse(jsonString); console.log(jsObject.name); // 输出: 小明 console.log(jsObject.age); // 输出: 25 -
JSON.stringify():将 JavaScript 对象转换为 JSON 字符串。- 当你需要将 JS 对象发送给服务器,或者存储到本地时,就需要用它把对象序列化成 JSON 字符串。
const jsObject = { product: "键盘", price: 199.5, colors: ["black", "white"] }; const jsonString = JSON.stringify(jsObject); console.log(jsonString); // 输出: {"product":"键盘","price":199.5,"colors":["black","white"]}- 注意:
JSON.stringify()默认会忽略函数、undefined、Symbol值。如果对象包含循环引用,会报错。
其他编程语言
-
Python: 使用
json模块的json.loads()(string to Python dict) 和json.dumps()(Python dict to string)。 -
Java: 通常使用第三方库如 Jackson 或 Gson 来处理 JSON。
-
PHP: 使用内置函数
json_decode()(string to PHP object/array) 和json_encode()(PHP object/array to string)。 -
Go: 使用内置的
encoding/json包。
6. JSON 与 XML 的对比 (简要)
在 JSON 流行之前,XML (Extensible Markup Language) 是数据交换的主要格式。它们各有优劣:
| 特性 | JSON | XML |
| :------- | :--------------------------------------- | :--------------------------------------------- |
| 可读性 | 简洁,易读 | 标签冗余,相对不那么直观 |
| 数据量 | 轻量级,数据量小 | 相对冗余,数据量较大 |
| 解析速度 | 更快,尤其是 JavaScript | 相对较慢 |
| 语法 | 结构化,严格,基于键值对和数组 | 基于标签和树状结构,更灵活,但可能更复杂 |
| 数据类型 | 支持 6 种基本类型 | 所有数据都是字符串,需额外解析 |
| Schema | JSON Schema (独立标准,非内置) | DTD / XML Schema (内置,强大) |
| 适用场景 | Web API,配置文件,日志,简单数据交换 | 文档标记,复杂结构化数据,需要自定义标签的场景 |
总结: JSON 在 Web 数据交换领域更受欢迎,因为它更轻量、解析更快,且与现代编程语言的数据结构天然契合。XML 仍然在一些传统企业系统、SOAP 服务和文档标记方面有应用。
7. JSON Schema (JSON 的‘数据校验规则书’)
你希望你的 JSON 数据总是长一个样子,并且符合一些特定的规则吗?比如,某个字段必须是字符串,必须是数字,必须存在,或者必须满足某个正则表达式?
这时候,你就需要 JSON Schema 了!
JSON Schema 是一种用于定义 JSON 数据的结构、约束和验证规则的规范。它本身也是一个 JSON 文档。你可以用它来:
-
验证 JSON 数据: 确保接收到的 JSON 数据符合预期的格式和类型。
-
文档化 JSON 格式: 清楚地说明你的 API 期望什么样的数据。
-
生成表单或代码: 根据 Schema 自动生成用户界面或客户端代码。
示例 (一个简单的 JSON Schema):
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "用户资料",
"description": "定义一个用户的基本资料结构",
"type": "object",
"required": ["name", "email"], // 必填字段
"properties": {
"name": {
"type": "string",
"description": "用户的全名",
"minLength": 3
},
"email": {
"type": "string",
"description": "用户的邮箱地址",
"format": "email" // 邮箱格式校验
},
"age": {
"type": "integer",
"description": "用户的年龄",
"minimum": 0
}
},
"additionalProperties": false // 不允许额外属性
}
通过 JSON Schema,你可以在应用程序中对 JSON 数据进行严格的校验,确保数据的完整性和正确性。
8. 安全性考量 (用 JSON,也得注意安全!)
尽管 JSON 本身是一种数据格式,但在使用它进行数据交换时,仍然需要注意一些安全问题:
-
反序列化漏洞 (Deserialization Vulnerabilities):
-
如果你在服务器端接收到恶意的 JSON 字符串,并使用不安全的反序列化库或方法将其转换为对象,攻击者可能会注入恶意代码,导致远程代码执行 (RCE) 等严重漏洞。
-
防范: 始终使用安全的反序列化库,并尽可能避免反序列化来自不可信源的任意代码。
-
-
跨站脚本攻击 (XSS) (Cross-Site Scripting):
-
如果你的应用程序接收用户输入的 JSON 数据,并在没有正确过滤或转义的情况下,将这些数据直接显示在网页上,攻击者可以注入恶意脚本,窃取用户数据或劫持用户会话。
-
防范: 永远对所有用户提供的数据进行严格的输入验证和输出转义(或 HTML 编码),无论数据是否以 JSON 格式传输。
-
-
JSON Hijacking (JSON 劫持):
-
在一些旧浏览器或特定配置下,恶意网站可能通过 JSON 数组或对象字面量窃取用户敏感的 JSON 数据。
-
防范: 现代 Web 框架和浏览器通常已提供防护。通常,GET 请求不应返回敏感 JSON 数据。对于敏感 JSON,使用 POST 请求,并添加 CSRF Token 或自定义请求头,以防止跨域读取。
-
-
敏感信息暴露:
- 永远不要在 JSON 中传输敏感信息(如密码、API Key、私人Token等)的明文! 即使是 Payload 中的信息也可能被解码。敏感信息应该只在加密通道(HTTPS)中,或者经过哈希、加密处理后传输。
总结
JSON 是一种简单、高效、通用且易于理解的数据交换格式。 它的键值对和数组结构使其与现代编程语言的数据模型完美契合。
从 Web API 到配置文件,从数据库存储到日志记录,JSON 已经渗透到互联网的方方面面,成为数据交换的事实标准。
掌握 JSON 的语法规则、数据类型、常见用途以及潜在的安全风险,是你成为一名合格开发者不可或缺的基本功!
希望这篇简明教程能让你对 JSON 有一个全面而深入的理解!