# 怎样比对两个 JSON 文件

两个 JSON 文件原样拿来比对，亮起来的大半什么都不是：缩进、折行、顺序不同的键。药方不是更聪明的比对——是先把两个文件过同一个格式化器，让剩下的只有真差异。两步都跑在你的浏览器里，而装着机密的配置文件就该待在那儿。

[打开文本比对](https://abox.tools/zh/text-diff/): 两段文本进来，每处差异都被标出来，逐行、逐词。没有一个字被贴进别人的服务器。

最后更新 2026年8月26日

## 简短的答案

1. 打开 [JSON 格式化](https://abox.tools/zh/json-formatter/)，贴入第一个文件，缩进设成两个空格，勾上“排序每个对象的键”。复制结果。
2. 打开[文本比对](https://abox.tools/zh/text-diff/)，贴进左边的框。
3. 第二个文件照做，贴进右边的框。

现在亮起来的是真的：变了的值、冒出来的键、消失的条目。会淹死普通比对的格式差异和换了位置的键都没了，因为比对开始之前，两边已经写成了同一种拼法。

两个页面都没有任何网络功能——这一点值得知道：人们拿来比对的 JSON，太多时候是凭据还躺在里面的配置文件。

## 为什么生比 JSON 几乎全是噪音

JSON 不在乎空白，也不给键的顺序赋予意义。同一份文档可以是一行，也可以是四百行；键可以按敲下的顺序排，也可以按某个库吐出的顺序排——工具改写这两样从不打招呼。一边压缩了，一边铺开了；一边手工存的，一边出自按字母排序的序列化器：逐行比对看见的是两个不相干的文件。

两个最糟的情形足以说明问题。**压缩过的**文件是一行，于是和它比对得到一条巨大无比的变更行——正确，且无用。而**内容相同、顺序不同**的两个文件会比出个处处皆变，诚实的答案本该是“什么都没变”。

![比较选项：并排或单栏视图、只显示改动行的开关，以及忽略空白、忽略大小写、忽略空行的开关。](https://abox.tools/screens/compare-two-json-files/options.webp)

正是它们，让一份文件只因为换行符不同就被报成整篇都改了的事不再发生。

## 格式化器的规范形修好了什么

两个文件过同一个格式化器、用同样的设置，正是比对需要的：一份文档一种拼法。

- **同样的缩进**让每个键各占一行：比对于是逐行工作，它的逐词标记也能指着一行里唯一变了的那个值。
- **排好序的键**让两边同序，顺序就不再是差异。排序按键读起来的样子，不按码位——`item2` 排在 `item10` 前——并且两边施加得一模一样。
- **其余分毫不动。**这个格式化器让数字保持你写下的每一位，保留重复的键而不是替你裁决：规范化自己变不出差异来。[格式化器指南](https://abox.tools/zh/guides/format-json-without-uploading-it/)解释了这为什么比理应的更稀罕。

一句诚实的但书：排序后的输出是键挪了位的文档。要是下游某个工具在乎键的顺序——在乎的不多，但存在——就把排序的副本当作被比对的东西，而不是原件的替身。

## 读结果，并带走它

比对把删掉的行标在左边、新增的行标在右边，变了的行里再把不同的词高亮出来：在规范形上，那通常就是从 `false` 挪到 `true` 的那一个值。没变的中段折叠成一个数字，两千行的配置改了三处，读起来就是三小段。

下载下来的是统一格式的补丁，一个 `.patch`——代码评审看得懂的格式。它描述的是规范形，而那通常正是评审想要的：只有改动，没有重排。

同一套做法对两个页面会说的其他东西同样有效。YAML 和 XML 用同样的路子化成规范形；来源不同、形状相同的两个文件，比对的忽略开关——空白、大小写、空行——就是同一想法的轻量版。

![同一份 JSON 配置的两个版本并排显示，改动过的行都有标记：版本号、重试次数、新增的开关和新增的地区。](https://abox.tools/screens/compare-two-json-files/diff.webp)

四处真正的差异，别的什么也没报。读是容易的那一半，活是上面那些设置干的。

## 如果你每周都做这件事

格式化两次、粘贴两次：步骤住在两个页面上，因为每页只干一件事，而且各自都能证明你贴的东西哪儿也没去。但两个都是开源的：MIT 许可证，零依赖的 ES 模块——格式化器的解析器保住键序和数位，比对是 Myers 算法——各配一份讲明白它的 README。

要是这已是你每天的一部分，把编码智能体指向[代码仓库](https://github.com/A-Box-of-Tools/website)，请它做一页两个框、边比对边规范化的页面：`parseJson`、`printJson` 和 `compareText` 只隔三个 import。这些模块写出来就是给人读的，把它们搬走，正是这份许可证存在的目的。
