本地工具箱 · 指南在线工具的使用说明与排障笔记

json对比工具怎么用?键序不同的两份 JSON 怎么比才不出假差异

本地工具箱 · 使用指南 · 2026-11-05 · 建议落地路径 /guide/json-diff-key-order-false-diff/

两份 JSON 明明数据一样,diff 出来却满屏红绿,九成是键序和缩进造成的假差异。用 json对比工具 的正确做法是先把两侧解析成结构、按字段名对齐再比,而不是拿两段文本逐行对。

先说结论

JSON 对象是无序的键值集合,键的前后位置不属于数据本身,键序不同不构成差异。

逐行文本对比(编辑器的 compare、git diff)找的是相同的行,键序一变行就错位,整段会被标成「删除 + 新增」,于是你看到一堆并不存在的改动。要判断两份 JSON 到底差在哪,必须走结构对比:解析、排序键名、按字段名递归对齐。

数组是另一回事。数组有序,按下标逐个比是符合语义的;但如果这个数组装的是「一批结果」,顺序本身没有业务含义,那就得先排序再比,否则每换一次返回顺序就报一遍差异。

为什么会这样

行级 diff 算法找的是公共行,不是公共字段。 文本对比常用的是最长公共子序列一类的算法,它把文件切成行,找出两边都存在的行块。一份 JSON 里有 "name"、"age"、"city" 三个键,左边顺序是 name、age、city,右边是 age、city、name,三行文本完全一样,只是位置换了,算法匹配出来的公共块立刻碎掉,输出的结果就是「左边删了三行、右边加了三行」。数据一个字没变,报告里却是六处改动。

JSON 规范本身就不保证对象有序。 RFC 8259 明确写了对象是无序的键值集合,字段的出现顺序不属于语义。解析器读进来通常存成哈希表或映射,写出时按自己的规则排序。这也解释了一个常见现象:同一份数据从 Java 服务、Go 服务、Node 服务分别返回,字段顺序往往各不相同,但它们是同一份数据。

数组的语义是位置,所以按下标比是对的。 ["a","b"] 和 ["b","a"] 是两个不同的数组,这一点没有争议。问题出在「数组装的是集合」的场景:分页查询返回的用户列表,数据库没有 ORDER BY 时每次顺序都可能变,按下标比对就会把这些波动当成差异,噪音盖住真正的改动。

还有一层是值的等价性。 数字 1 与 1.0 在多数语言里是同一个数,序列化回文本却不同;字符串里的 \u4e2d 和 中 解析后完全相等;null 和「这个键不存在」是两件事,但在很多 diff 里都显示为空;重复键只保留最后一个,前面的被静默丢弃。这些都不是工具算错,是「比字节」和「比语义」的区别。

所以真正要决定的不是用哪个工具,而是这次要比什么:比接口契约,就比结构的增减;比数据是否一致,就比值;比发布包有没有变,才轮到比字节。

具体怎么做

  1. 先把两份原始返回各存一份。 用 curl -s url > before.json 这样的方式落盘,别只留在浏览器请求记录里。后面确认「是环境差异还是真改坏了」,全靠这份原始件。
  1. 各自格式化一遍,消掉缩进和空白的噪声。 拿在线 JSON 格式化贴进去,它会补全键名的双引号、统一缩进,还能切换正序与倒序。这一步做完,两份文件的排版基准就一致了。
  1. 确认不要用「压缩成单行」的版本去比。 压成一行之后,行级 diff 完全失去意义,整份文件会被当成一行处理,红了就是全红。
  1. 打开 JSON 对比,左旧右新粘贴。 左边放改动前的、右边放改动后的,方向不要反,否则新增和删除的颜色会整体互换。贴错了就点「交换左右」,不用重新复制。
  1. 看两侧键名有没有排到同一顺序。 页面默认按键名正序排列,也可以切到倒序,两侧会同步。键名比较是区分大小写的,userId 和 userid 在 JSON 里是两个不同的键,这类差异要当结构问题处理,不是笔误。
  1. 按颜色分层处理,先结构后取值。 红色表示右侧缺少这个字段,绿色表示右侧新增,橙色表示两侧都有但值不同。先清红绿——那是结构变动,往往对应一次字段增删;橙色属于取值变化,逐条核对即可。
  1. 看统计数字,再复制差异清单。 新增、删除、修改三个计数能快速判断这次改动量级:只有橙色的通常是数据变化,出现红绿就说明契约动了。清单可以直接复制进工单或代码评审评论,比截图清楚。
  1. 数组差异单独看一眼。 如果差异全部集中在某个数组内,先确认这个数组有没有业务顺序。没顺序的,把元素按主键(id 之类)排一遍再比,噪音会立刻消失。
  1. 涉敏数据先脱敏再比。 这两个工具都在浏览器本地完成比对,输入不会发到服务器;但返回里带 token、手机号、密钥的,仍然建议替换成占位符再贴,截图也不要随手发群里。

参数对照

差异类型逐行文本对比的表现按字段名对比的表现处理建议
对象内字段换了位置整段报删除 + 新增通常零差异无视,属正常序列化差异
缩进、空格、换行不同每一行都不同零差异先格式化再比
某个字段的值变了报差异,但定位在行报橙色,定位到具体字段逐字段核对取值
右侧缺字段 / 多字段报差异且位置错乱红 / 绿标在父级下按结构变动处理,同步契约
数组元素顺序不同报差异报差异(按下标比)先按业务主键排序
类型不同(1 与 "1")报差异报差异,同色标出先确认是不是序列化 bug

表格里的判断只解决「差异长什么样」,不解决「哪个是对的」。哪份符合契约,要回去看接口文档或 JSON Schema,diff 工具不承担这件事。

常见误区

以为没有红绿就是完全一致。 工具比的是两侧都存在的字段,一侧整体缺失的子树只会标在父级上。父级字段整个消失时,下面十几个子字段不会逐个冒红,看统计里的「删除」计数更靠谱。

以为 diff 能替代 schema 校验。 差异对比只回答「两份哪里不同」,不回答「这份合不合规范」。两份都错的 JSON 比出来可能零差异,那不代表它是对的。

以为键序不同一定要修。 对象键序不是契约的一部分,绝大多数解析器不关心。真正该在意顺序的是数组,而数组要不要在意顺序,取决于接口有没有承诺排序。

以为本地处理就等于绝对安全。 本地处理只是说内容不上传服务器,浏览器扩展、输入法云同步、剪贴板历史仍然可能把内容带走。工具这一环是干净的,环节之外不是。

常见问题

问:json对比工具会把接口数据传到服务器吗? 取决于实现。标了本地处理的工具,比对在浏览器里跑完,输入不发到后端,断网后依然能对比——这也是一种验证办法。含密钥、手机号、身份证号的返回,建议先替换成占位符再贴,无论用哪个网站。

问:两份 JSON 键顺序不一样,diff 出来全是红绿怎么办? 说明用的是逐行文本对比,换掉即可。按字段名对齐的结构对比不受键序影响,两侧键名会自动排到同一顺序再逐字段比,键序差异直接归零。

问:数组里对象的顺序变了,算不算差异? 看接口有没有承诺顺序。按下标比对一定报差异;如果业务上顺序无意义(分页结果、批量查询),先按主键排序再比,否则每次返回顺序波动都会被记成改动。

问:为什么 1 和 1.0 会被标成不同? 因为它们在序列化后的文本里不一样。比较时若按原始字面量走,就会报差异;按数值走则相等。遇到这种差异先查两侧的序列化库:Java 的 BigDecimal、Python 的 float、Go 的 float64 输出格式各不相同。

问:大整数 ID 比对时对不上是怎么回事? 超过 2^53 的整数在 JavaScript 里会丢精度,9007199254740993 读进来会变成 ...992。这类 ID 应当以字符串传输,比对前先确认两侧都没被截断,否则差异是精度造成的,不是数据本身。


要现成的话,直接用 JSON 对比 把两份 JSON 左右贴进去,结构、颜色和差异清单一次看完。

需要直接打开工具?前往 本地工具箱首页,66 个工具免注册使用;本页提到的每个功能都有独立地址,可单独收藏。