JSON 数据交互规范

1.5 JSON 数据交互规范

JSON(JavaScript Object Notation)是轻量级文本数据交换格式,也是前后端交互、本地数据持久化的事实标准。

它基于 JavaScript 语法子集设计,但完全独立于编程语言,被所有主流语言原生支持,具备体积小、可读性强、解析效率高的特点,是前端交互开发中数据传输与存储的核心载体。


1.5.1 JSON 语法规则与约束

JSON 的语法是 JavaScript 对象字面量的严格子集,相比普通 JS 对象有更强的约束,不符合规范的 JSON 字符串无法被标准解析器识别。

一、核心语法规则
  1. 键值对结构:数据以「键:值」形式组织,键名必须使用双引号包裹,不可使用单引号或无引号
  2. 数据分隔:多个键值对、数组成员之间用英文逗号分隔,最后一项后禁止添加尾随逗号
  3. 结构标识:对象使用花括号 {} 包裹,数组使用方括号 \[\] 包裹
  4. 字符串值:字符串类型的值必须使用双引号包裹,不可使用单引号
  5. 无注释:JSON 标准不支持任何形式的单行或多行注释
二、支持的数据类型

|----------|-------------------|---------------------------------|
| 类型 | 说明 | 合法示例 |
| 字符串 | 双引号包裹的 Unicode 字符 | "hello"" 张三 " |
| 数字 | 整数、浮点数,支持科学计数法 | 1233.141e5 |
| 布尔值 | 全小写的 true /false | truefalse |
| null | 空值标识,全小写 | null |
| 对象 | 花括号包裹的键值对集合 | {"name": " 张三 "} |
| 数组 | 方括号包裹的有序集合 | 1, 2, 3 |

三、常见语法错误

以下写法均为非法 JSON,解析时会直接报错:

  • 键名使用单引号:{'name': ' 张三 '}
  • 键名省略引号:{name: " 张三 "}
  • 字符串值用单引号:{"name": ' 张三 '}
  • 末尾多余逗号:{"name": " 张三 ", "age": 25,}
  • 包含注释:{"name": " 张三 " /* 用户名 */}
  • 包含 undefined / 函数:{"fn": function(){}}

标准合法 JSON 示例:

javascript 复制代码
{

  "sites": [

    { "name": "菜鸟教程", "url": "www.runoob.com" },

    { "name": "google", "url": "www.google.com" },

    { "name": "微博", "url": "www.weibo.com" }

  ],

  "total": 3,

  "success": true,

  "error": null

}

1.5.2 序列化与反序列化核心方法

JavaScript 内置全局 JSON 对象,提供两个核心方法实现 JSON 字符串与 JS 对象的双向转换,是前后端数据交互的必用语法。

一、JSON.parse ():JSON 字符串 → JS 对象

将符合规范的 JSON 字符串解析为原生 JavaScript 对象,常用于解析后端接口返回的响应数据。

语法:

JSON.parse(text, reviver)

  • text:待解析的 JSON 字符串
  • reviver(可选):转换回调函数,遍历每个键值对,可对解析结果做二次处理

基础示例:

javascript 复制代码
const jsonStr = '{"name":"前端开发","year":2024,"isUseful":true}';

const jsObj = JSON.parse(jsonStr);



console.log(jsObj.name); // 输出:前端开发

console.log(jsObj.year); // 输出:2024

进阶:reviver 字段预处理

常用于将日期字符串自动转换为 Date 对象:

const str = '{"name":"张三","birth":"1998-01-01"}';

const user = JSON.parse(str, (key, value) => {

  if (key === 'birth') return new Date(value);

  return value;

});
二、JSON.stringify ():JS 对象 → JSON 字符串

将 JavaScript 值序列化为符合规范的 JSON 字符串,常用于向后台提交数据、本地存储对象。

语法:

JSON.stringify(value, replacer\[, space])

  • value:待序列化的 JS 值(通常为对象、数组)
  • replacer(可选):过滤规则,可为数组或函数,控制需要序列化的属性
  • space(可选):缩进空格数,用于美化输出格式,提升可读性

美化格式示例:

javascript 复制代码
const user = {

  username: "张三",

  age: 25,

  skills: ["HTML", "CSS", "JS"]

};



const prettyJson = JSON.stringify(user, null, 2);

console.log(prettyJson);

进阶:replacer 过滤敏感字段

const user = { name: "张三", password: "123456", age: 25 };



// 传入数组:只序列化指定属性

const safeStr1 = JSON.stringify(user, ["name", "age"]);



// 传入函数:自定义序列化逻辑

const safeStr2 = JSON.stringify(user, (key, value) => {

  if (key === "password") return undefined; // 过滤敏感字段

  return value;

});
三、前端典型应用场景
  1. 接口交互:接收后端响应后调用 JSON.parse 解析;提交请求前调用 JSON.stringify 序列化请求体
  2. 本地存储:localStorage /sessionStorage 仅支持字符串存储,保存对象 / 数组时必须先序列化
  3. 简易深拷贝:通过 JSON.parse(JSON.stringify(obj)) 实现对象深拷贝(存在边界限制,见下节)
  4. 数据快照:记录数据状态,用于撤销重做、对比差异

1.5.3 序列化边界与异常场景

JSON 序列化并非支持所有 JavaScript 类型,存在明确的边界与异常行为,是开发中高频踩坑点。理解这些边界可以避免数据丢失、解析报错等线上问题。

一、序列化的类型边界

JSON.stringify 对不同类型的处理规则:

|-------------------------------------------------|---------------------|-------------------------------------|
| JS 类型 | 序列化结果 | 说明 |
| 字符串、数字、布尔值 | 正常转换为对应 JSON 类型 | 符合预期 |
| null | 保留为 null | 符合预期 |
| undefined | 对象属性被忽略,数组成员转为 null | 对象中该属性直接消失 |
| 函数、 Symbol | 对象属性被忽略,数组成员转为 null | 无法序列化 |
| NaN Infinity -Infinity | 转为 null | 数字特殊值会丢失语义信息 |
| Date 对象 | 转为 ISO 格式字符串 | 调用 toISOString(),解析后为字符串而非 Date |
| RegExp Error 对象 | 转为空对象 {} | 丢失全部内部信息 |
| Map Set WeakMap 等集合 | 转为空对象 {} | 无法直接序列化 |
| 循环引用对象 | 直接抛出错误 | 检测到循环引用时报错终止 |

二、常见异常场景
  1. 循环引用报错
  2. 当对象内部存在循环引用(对象属性指向自身)时,序列化会直接抛出 TypeError。
javascript 复制代码
const obj = {};

obj.self = obj;

JSON.stringify(obj); // 抛出错误:Converting circular structure to JSON
  1. 属性静默丢失
  2. 对象中的 undefined、函数、Symbol 属性会被静默删除,导致数据不一致。
javascript 复制代码
const data = {

  a: undefined,

  b: function() {},

  c: Symbol('id')

};

console.log(JSON.stringify(data)); // 输出:'{}',所有属性全部丢失
  1. 特殊数字失真
  2. NaN、无穷大会被转为 null,数值语义丢失。
javascript 复制代码
const nums = [NaN, Infinity, -Infinity];

console.log(JSON.stringify(nums)); // '[null,null,null]'
  1. 格式解析失败
  2. 传入不符合 JSON 规范的字符串时,JSON.parse 会直接抛出语法错误,导致程序中断。
javascript 复制代码
JSON.parse('{name: "张三"}'); // 抛出 SyntaxError
三、工程避坑指南
  1. 接口数据统一做容错处理:JSON.parse 外层包裹 try/catch,避免格式错误导致页面崩溃
  2. 复杂对象深拷贝优先使用结构化克隆 structuredClone(),替代 JSON 序列化方案
  3. 序列化前清理敏感字段与不可序列化字段,避免数据静默丢失
  4. 日期类型统一约定传输格式,解析后显式转换为 Date 对象,避免字符串日期导致的计算错误
  5. 大文件、复杂集合类型不使用 JSON 传输,选择 FormData 或二进制格式
相关推荐
工业HMI实战笔记14 小时前
玩具制造HMI:注塑成型的快速换模与质量监控界面
人工智能·学习·交互·制造
兰亭妙微UI设计公司19 小时前
UI设计外包项目复盘沉淀|兰亭妙微:交互设计复盘,到底要写哪些内容
交互
躺柒1 天前
读数据可视化29可视化中的交互(下)
信息可视化·人机交互·交互·可视化·数据可视化·交互技术
Wang's Blog2 天前
Java框架快速入门: Spring Security+OAuth2之自定义认证过滤器实现JSON登录
java·spring·json
淼澄研学2 天前
Win11 Dev Home与WinGet实操:基于JSON的声明式环境配置指南
json
云雀衔光2 天前
MCP + 应用生成:让 AI 直接产出可交互的应用
java·人工智能·测试工具·microsoft·交互·ai编程
可乐鸡翅yeah_2 天前
开发调试高频痛点解决,一站式在线加密解密与编码转换实战
json·加密解密·json在线转换
小疯仔2 天前
轨迹在地图上“漂“了 500 米?一文吃透 WGS-84→GCJ-02 坐标转换引擎(GPX→JSON 实战源码剖析)
小程序·json·notepad++
Flynt3 天前
"只输出 JSON"根本不够:LLM 结构化输出的坑,我实测了 60 次调用
llm·json
smartpi_ai3 天前
自学习“放着不动“会自动退出吗?超时退出缺席的交互兜底、退出条件挂串口的状态联动设计
学习·microsoft·交互