JSON 结构分析
格式化所有处理都在浏览器本地完成,数据不上传服务器
把 JSON 粘进来,得到一份结构画像:嵌套层数、节点总数、对象与数组的个数、各类型的占比、最长的数组与最长的字符串。 最值得看的一项是重名键。 `JSON.parse('{"a":1,"a":2}')` 得到 `{"a":2}`,第一个 `a` 安静地消失了,没有任何提示。而在接口对接里这很实际:服务端两个地方各写了一次同一个字段,两边看「同一份 JSON」时得出的结论不一样,排查时会互相怀疑对方看错了。这个工具会扫原始文本找出它们,并给出所在路径。 为什么它和「JSON 格式化」是两个工具:那个回答「怎么看这段 JSON」(排版、折叠、改值),这个回答「这段 JSON 是什么」(多大、多深、什么构成)。输入一样,要做的事与界面完全不同 —— 把统计塞进那个已经塞满按钮的编辑器上,对两边都不好。 另外三个动作是递归的:洗牌、反转、去重都会作用到每一层的数组,而不只是最外层。
功能
- 嵌套层数、节点总数、对象与数组个数
- 各类型的分布(string × 12、number × 5 …),按数量从多到少排
- 最长的数组有多长,并列出全部数组的长度
- 最长的字符串有多长、字符串总长度
- ⚠️ 重名键:扫原始文本找出同一个对象里重复的键,给出路径与次数,并说明 `JSON.parse` 只保留最后一个
- 洗牌 / 反转 / 去重三个动作,递归作用到所有层级的数组
- 去重按值的 JSON 文本判重 —— `1` 与 `"1"` 是两回事,两个一样的对象是一回事
- 解析复用「JSON 格式化」那份错误定位(带行列号,并能认出 Python 字面量)
- 全部在浏览器本地完成,不联网
使用方法
- 把 JSON 粘进输入框
- 「做什么」选结构统计,右侧立刻给出各项数字
- 看「重名键」那一行 —— 没有也会明确写「没有」
- 要整理数据就选洗牌 / 反转 / 去重,结果是格式化好的 JSON
常见问题
- 重名键为什么是问题?我的代码读到的值看着是对的
- 因为你读到的是最后一个。`JSON.parse` 遇到重复键会保留后一个、丢弃前一个,而丢掉的时机是解析、不是读取 —— 所以你拿到的值是「对」的,只是它不一定是你以为的那个来源。真正的麻烦在协作时:服务端说「我明明返回了 A」,你贴出来的 JSON 里 A 确实在(第一次出现),但你的代码拿到的是后面那个 B。这个工具把两处都指出来,你们就能对着同一个位置讨论。
- 为什么不说「JSON 必须没有重名键」?
- 因为规范确实没禁止(RFC 8259 说行为未定义、由实现决定),所以各家解析器表现不一:JavaScript 保留最后一个,Python 的 json 也是,而有的严格解析器会直接报错。同一份文件在不同语言里得到不同结果,这正是它危险的地方。这个工具不做判断,只把事实列出来。
- 「嵌套层数」从几开始算?
- 根节点算第 1 层。`{"a":1}` 的层数是 2(根对象 + 数字),`{"a":{"b":1}}` 是 3。这样算的好处是「层数 = 从根走到最深那个值要经过几个节点」,比按「有几层花括号」直觉一些。
- 洗牌用的是真随机吗?
- 用 `Math.random`,是 Fisher–Yates 洗牌。⚠️ 这里不用 `crypto.getRandomValues`,因为它的用途是「让数据的顺序变得不可预测」而不是密码学 —— 想要不可预测的随机值(密码、令牌)请用「密码生成器」或「随机数」那两个工具。
相关工具
JSON 格式化
格式化在线 JSON 格式化与校验工具:树形折叠浏览、搜索键值、逐节点改值与删除、语法错误定位到具体行列,输入框带行号与高亮。全部在浏览器本地完成。
JSON 转代码
格式化把 JSON 样本转成 TypeScript interface、Go struct、Java class 或 Rust struct:不齐的键标成可选、类型冲突退化为联合类型。全程在浏览器本地生成。
JSONL 转换
格式化JSONL(NDJSON)与 JSON 数组双向互转:逐行解析并指出出错的行号,自动跳过空行、处理 CRLF 与 BOM。全部在浏览器本地完成。
SQL 格式化
格式化在线 SQL 格式化:关键字统一大小写、按 SELECT / FROM / WHERE 等子句换行缩进、子查询逐层展开,压缩模式去掉多余空白与注释。语句不上传服务器。
JSON5 转换
格式化把 JSON5 解析成标准 JSON:注释、无引号键、单引号、尾逗号、十六进制、Infinity 都支持,错误指出行列。全部在浏览器本地完成。
XML 格式化
格式化在线 XML 格式化、压缩与属性排序:按标签层级缩进,属性可按名字排序(对比两份 XML 时用)。全程在浏览器本地完成。