# 怎樣比對兩個 JSON 檔案

兩個 JSON 檔案原樣拿來比對，亮起來的大半什麼都不是：縮排、折行、順序不同的鍵。藥方不是更聰明的比對——是先把兩個檔案過同一個格式化器，讓剩下的只有真差異。兩步都跑在你的瀏覽器裡，而裝著機密的配置檔案就該待在那裡。

[開啟文字比對](https://abox.tools/zh-TW/text-diff/): 兩段文字進來，每處差異都被標出來，逐行、逐詞。沒有一個字被貼進別人的伺服器。

最後更新 2026年8月26日

## 簡短的答案

1. 開啟 [JSON 格式化](https://abox.tools/zh-TW/json-formatter/)，貼入第一個檔案，縮排設成兩個空格，勾上「排序每個物件的鍵」。複製結果。
2. 開啟[文字比對](https://abox.tools/zh-TW/text-diff/)，貼進左邊的框。
3. 第二個檔案照做，貼進右邊的框。

現在亮起來的是真的：變了的值、冒出來的鍵、消失的條目。會淹死普通比對的格式差異和換了位置的鍵都沒了，因為比對開始之前，兩邊已經寫成了同一種拼法。

兩個頁面都沒有任何網路功能——這一點值得知道：人們拿來比對的 JSON，太多時候是憑據還躺在裡面的配置檔案。

## 為什麼生比 JSON 幾乎全是噪音

JSON 不在乎空白，也不給鍵的順序賦予意義。同一份文件可以是一行，也可以是四百行；鍵可以按敲下的順序排，也可以按某個庫吐出的順序排——工具改寫這兩樣從不打招呼。一邊壓縮了，一邊鋪開了；一邊手工存的，一邊出自按字母排序的序列化器：逐行比對看見的是兩個不相干的檔案。

兩個最糟的情形足以說明問題。**壓縮過的**檔案是一行，於是和它比對得到一條巨大無比的變更行——正確，且無用。而**內容相同、順序不同**的兩個檔案會比出個處處皆變，誠實的答案本該是「什麼都沒變」。

![比較選項：並排或單欄檢視、只顯示改動行的開關，以及忽略空白、忽略大小寫、忽略空行的開關。](https://abox.tools/screens/compare-two-json-files/options.webp)

正是它們，讓一份檔案只因為換行符不同就被報成整篇都改了的事不再發生。

## 格式化器的規範形修好了什麼

兩個檔案過同一個格式化器、用同樣的設定，正是比對需要的：一份文件一種拼法。

- **同樣的縮排**讓每個鍵各佔一行：比對於是逐行工作，它的逐詞標記也能指著一行裡唯一變了的那個值。
- **排好序的鍵**讓兩邊同序，順序就不再是差異。排序按鍵讀起來的樣子，不按碼位——`item2` 排在 `item10` 前——並且兩邊施加得一模一樣。
- **其餘分毫不動。**這個格式化器讓數字保持你寫下的每一位，保留重複的鍵而不是替你裁決：規範化自己變不出差異來。[格式化器指南](https://abox.tools/zh-TW/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。這些模組寫出來就是給人讀的，把它們搬走，正是這份許可證存在的目的。
