Skip to content

JSON Diff 对比

在浏览器中即时对比两份 JSON。Side-by-Side 高亮 + RFC 6902 JSON Patch 输出,一键忽略 timestamps、IDs 等噪音字段。100% 隐私保护,零上传。

无追踪 浏览器中运行 免费
Ignore paths:
高级选项
Array 模式
已针对 RFC 6902/6901 兼容性及 null vs missing keys、type drift、浮点精度、数组 key 对齐等边界场景做 review。 — Go-Tools API 工具团队 · 2026年5月4日

什么是 JSON Diff?

JSON Diff 是基于 JSON 数据模型的两份文档结构化对比 —— 键序无关、类型严格、数组可有序或按 key 对齐。和文本 diff(按行比较,把键重排或空白当作差异)不同,JSON diff 给出的是有语义的结果。

规范的机器可读形式是 JSON Patch (RFC 6902),一组有序 ops 数组(add、remove、replace、move、copy、test),把一份文档变换为另一份。路径用 JSON Pointer (RFC 6901) 表达。相关:JSON Merge Patch (RFC 7396) —— 更简单,但无法区分「删除 key」与「设为 null」。本工具输出 RFC 6902。

JavaScript 里的 JSON 深度相等比看上去要难。JSON.stringify(a) === JSON.stringify(b) 在键序变化时就会出错,对 -0 vs 0(都序列化为 "0")也会误判。正确的 diff 必须用键集合并集并行遍历两棵树,用 'in' 操作符区分 null 与 missing,并明确「相等」对数字意味着什么(默认 Object.is,需要容差时用 epsilon)。

本工具完全在你的浏览器中运行。输入永不离开你的设备。可放心处理 API 响应、内部 schema 和私有配置。

配套 JSON 工具:JSON 格式化JSON 转 YAMLYAML 转 JSON。 进阶 timestamp/ID 过滤模式见 配套博客

// Two JSON documents that look different but are semantically equal
const a = '{"a":1,"b":2}';
const b = '{"b":2,"a":1}';

// Naive comparison — wrong
JSON.stringify(JSON.parse(a)) === JSON.stringify(JSON.parse(b));
// → false (key order differs)

// JSON Diff (this tool) — correct: key order is irrelevant
// → 0 differences

// JSON Patch (RFC 6902) for { "a": 1 } → { "a": 2 }
// [{ "op": "replace", "path": "/a", "value": 2 }]

核心特性

Side-by-Side + JSON Patch 双视图

一份 diff 两种视图:可视化高亮供人 review,RFC 6902 patch 供自动化处理。

一键忽略噪音字段

预设按钮一键过滤 /createdAt、/updatedAt、/*Id、/*At、requestId、traceId。也支持自定义 Extended JSON Pointer 模式。

数组按 key 对齐

对象数组按 id 字段而非 index 比较 —— 适合 K8s envs、package-lock 条目,或任何逻辑无序列表。

默认 Type-Strict

1 ≠ "1"。null ≠ missing。一进 test fixture 就抓住后端序列化漂移。

100% 浏览器内运行

输入永不离开你的设备。零上传、零 localStorage 持久化 JSON、零分析你粘贴的内容。

Share Link 只分享配置

Share Link 只把配置写入 URL,你的 JSON 输入始终留在本地。

示例

API 响应回归对比

{"user":{"id":1,"name":"Ada","createdAt":"2024-01-01"}}
{"user":{"id":1,"name":"Ada Lovelace","createdAt":"2024-02-02"}}

两处变化(name + createdAt)。把 /user/createdAt 加入 Ignore paths,只剩 name 这一处真实变更。

配置文件审计(键序变化)

{"a":1,"b":2,"c":3}
{"c":3,"a":1,"b":2}

数据相同、键序不同。JSON Diff 将键序视为语义无关 —— diff 结果为空。

对象数组(按 key 对齐)

[{"id":1,"qty":3},{"id":2,"qty":5}]
[{"id":2,"qty":5},{"id":1,"qty":4}]

把 Array mode 切到「Match by key」并填 key=id。不对齐时每个元素都像变了;对齐后只有 id=1 的 qty 变化。

JSON Patch 输出(RFC 6902)

{"items":[{"id":1,"price":29.99}]}
{"items":[{"id":1,"price":24.99}]}

切到 JSON Patch 标签页可获得 [{"op":"replace","path":"/items/0/price","value":24.99}],可直接喂给 fast-json-patch。

使用方法

  1. 1

    粘贴两份 JSON

    把原始(左)和修改后(右)JSON 粘贴进来。边输入边渲染 live diff;大输入(>200 KB)会切换到手动 Diff 按钮。

  2. 2

    过滤噪音

    点预设(Timestamps / IDs / Trace)或粘贴 Extended JSON Pointer 模式到 Ignore paths,去掉无关字段。

  3. 3

    选择需要的视图

    Side-by-Side 适合人眼 review,JSON Patch (RFC 6902) 适合机器自动应用。点 Share Link 把配置发给同事。

常见 Diff 陷阱

键序噪音(文本 diff 症状)

如果你的 diff 工具把 {"a":1,"b":2} 和 {"b":2,"a":1} 报为不同,那是行 diff 不是 JSON diff。JSON 键序无关 —— 本工具自动忽略键序。

✗ 错误
diff a.json b.json   # text diff: 'everything changed'
✓ 正确
JSON Diff (this tool): 0 differences

Null vs Missing 混淆

{"a":null} 和 {} 不同。把它们视为相同会掩盖真实的后端 bug。

✗ 错误
{"a": null} == {}   # collapsed by some tools
✓ 正确
{"a": null} ≠ {}     # type-strict diff

数组未对齐 key 就比较

对逻辑集合 [{id:1},{id:2}] vs [{id:2},{id:1}] 不应是「两处变化」。Sequential 会这么报;切到 Match by key。

✗ 错误
Sequential diff: 4 modified
✓ 正确
Match by key (id): 0 differences

类型漂移(数字 vs 字符串)

后端有时序列化 ID 不一致 —— 42 vs "42"。本工具把这类标为 'type' 修改,让你早期发现漂移。

✗ 错误
{"id": 42} vs {"id": "42"}   # serialization bug
✓ 正确
Diff reports 'modified (type)' with both values

浮点精度

0.1 + 0.2 !== 0.3(IEEE 754)。tolerance=0(默认)时会被标为差异。如果你想让它们相等,设 tolerance 为 1e-9。

✗ 错误
tolerance=0:  0.30000000000000004 ≠ 0.3
✓ 正确
tolerance=1e-9: equal

Timestamp 与 UUID 噪音

createdAt、updatedAt、requestId、traceId 每次请求都变。用 Ignore paths 预设把它们抹掉。

✗ 错误
Diff: 47 modifications (45 are timestamps)
✓ 正确
Add /createdAt, /updatedAt, /requestId to Ignore paths → 2 real changes

常见使用场景

API 响应回归
对比 staging 与 production 的响应;忽略 timestamps 和 request IDs,只暴露真正有意义的 payload 变化。
CI Snapshot 测试失败
把失败的 Jest/Vitest snapshot 的 actual vs expected 粘进来。秒级过滤噪音找出真实变化。
package-lock / yarn.lock 冲突
按 name 对齐依赖来解决合并冲突;键序和无关字段不再是噪音。
K8s / Helm Values 审计
按 name 对齐 envs、volumeMounts、ports。识别误改顺序与真实配置变更。
i18n 翻译完整性检查
对 en.json 与 zh.json 做结构 diff,找出缺失或多余的翻译 key,避开值噪音。
Terraform / CDK Plan 复核
对比多次 plan 输出;numeric tolerance 处理浮点运算,ignore paths 抹掉 ARN 和 timestamps。

技术细节

RFC 6902 兼容的 Patch 输出
生成合法的 JSON Patch ops(add/remove/replace),路径符合 RFC 6901。已与 fast-json-patch@3.x 和 rfc6902 npm 包交叉校验。
迭代式遍历
显式栈遍历(不递归),上限 100,000 节点 + 深度 64,防止恶意输入触发栈溢出。
Object.is 数值相等
默认 numeric tolerance 为 0 —— 用 Object.is,所以 -0 与 +0 严格区分。设置 tolerance > 0 进入 epsilon 比较。

最佳实践

先过滤再 review
先加 Ignore paths(timestamps、IDs、trace 字段),再读 diff。看噪音满屏的 diff 会让眼睛习惯性跳过 —— 然后错过真正的变化。
逻辑集合用 Match by key
如果你的数组表示无序集合(envs、users、依赖项),就用 Match by key。对逻辑集合做 Sequential diff 几乎肯定是错的。
Share Link 不要 share 输入
用 Share Link 把过滤配置发给同事 —— 永远不要把敏感 JSON 粘到共享文档。URL 里只有配置。

常见问题

为什么我只改了一个字段,diff 却显示满屏变化?
三个常见嫌疑:(1) 键序不同 —— JSON Diff 视键序为等价,但文本 diff 工具不会;(2) timestamps、UUIDs、自增 ID 每次请求都会变 —— 加入 Ignore paths;(3) 数组顺序不应按 index 比较 —— 把 Array mode 切到「Match by key」。
如何在 JSON diff 中忽略 timestamps 和 IDs?
使用上方的 Ignore paths 输入框。点「Timestamps」或「IDs」预设按钮一键过滤 /createdAt、/updatedAt、/*Id、/*At、/requestId。也可以粘贴自定义的 Extended JSON Pointer 模式 —— 每行一条 —— 实现进阶过滤。
JSON Patch 和 visual diff 有什么区别?
Visual(side-by-side)diff 给人看 —— 用眼睛 review 变化。JSON Patch (RFC 6902) 给机器吃 —— 一组结构化 ops 数组(add/remove/replace),可用 fast-json-patch 或 rfc6902 npm 包直接 apply。同一份 diff,两种输出。
JSON diff 把 null 和缺失的 key 视为相同吗?
不。{"a":null} 和 {} 不同 —— 前者显式 null,后者无该 key。真实系统对两者行为不同;本工具严格区分。
数组按什么对比 —— index 还是 key?
默认按 index(Sequential)。切到「Match by key」并填 key 字段(通常是 id)即可不论顺序对齐元素。适合 K8s envs、package-lock 条目,或任何逻辑上是「集合」的列表。
可以导出为 RFC 6902 JSON Patch 吗?
可以。JSON Patch 标签页输出合法的 RFC 6902 ops 数组。设置了 Ignore paths 时 patch 会被过滤(标签页显示「(filtered: excludes N ignored paths)」),无法完整 round-trip。需要完整 patch 请清空 Ignore paths。
JSON Patch 和 JSON Merge Patch (RFC 7396) 是同一个吗?
不。RFC 6902(JSON Patch)是有序 ops 数组 —— 显式且可逆。RFC 7396(Merge Patch)是单一合并文档 —— 更简单但无法区分「删除 key」和「将 key 设为 null」。JSON Diff 输出 RFC 6902。
如何对比超过 10 MB 的大 JSON 文件?
超过约 5 MB 的文件会超出浏览器实际内存。Live 模式在 200 KB 时会自动关闭;多 MB 量级请用命令行 jq 或 Node 中的 fast-json-patch。
本工具会把 JSON 上传到服务器吗?
不会。所有比较都在你的浏览器本地完成。输入永不写入磁盘、网络、localStorage 或 URL 参数。刷新页面即清空。Share Link 按钮只写配置(Array mode、Ignore paths),永远不会写你的数据。
为什么 42 和 "42" 在 diff 中不一样?
JSON Diff 是 type-strict 的:数字 42 和字符串 "42" 不相等。这有助于你早期发现后端序列化漂移(有些 endpoint 返回数字 ID,有些返回字符串)—— diff 会标记为 'type' 修改。
可以 diff 含注释(JSONC)或尾逗号的 JSON 吗?
标准 JSON(RFC 8259)不允许注释或尾逗号。本工具用原生 JSON.parse,两者都会拒绝。请先用 JSON 格式化工具 去除注释。
如何按 id 这样的 key 对比嵌套对象数组?
把 Array mode 设为「Match by key」并填 id。Diff 会按 id 值对齐。v1 在每一层数组都用同一个 key 字段;内层数组若没有该字段则 fallback 到 sequential 并显示 warning chip。
Diff 能处理浮点精度(0.1 + 0.2)吗?
能,通过 Numeric tolerance。默认 0 + Object.is —— 所以 -0 vs +0 也会被标。设为小 epsilon(如 1e-9),0.1 + 0.2 就会与 0.3 视为相等。容差仅作用于数字叶子节点。

Base64 解码与编码工具

编码和格式化

免费在线 Base64 解码编码工具。实时转换,支持中文和 Emoji,100% 浏览器端运行,数据不离开设备,无需注册。

JSON 格式化与验证工具

编码和格式化

在浏览器中即时格式化、验证和美化 JSON。免费在线工具,支持语法验证、错误检测、压缩和一键复制,100% 隐私保护。

JSON 转 YAML 转换器

编码和格式化

粘贴 JSON 即时获得 YAML,浏览器端实时转换。支持 Kubernetes、Docker Compose 和 Terraform,提供 2/4 空格缩进、Norway 安全自动引号,100% 隐私保护,数据不离开设备。

URL 编码解码在线工具 — 内置 URL 结构解析

编码和格式化

粘贴 URL 即时编码或解码,实时显示结果。内置 URL 解析器将协议、域名、路径、查询参数拆解为可编辑字段。支持 encodeURI 和 encodeURIComponent 双模式切换,检测双重编码问题。纯浏览器端运行,数据不离开设备。

YAML 转 JSON 转换器

编码和格式化

粘贴 YAML 即时获得 JSON,浏览器端实时转换。支持 K8s 清单、OpenAPI 规范、Helm values 和 Ansible playbook,完整展开锚点/别名,100% 隐私保护,数据不离开设备。

进制转换器 — 二进制、十六进制、十进制、八进制互转

转换工具

在线免费进制转换工具,支持二进制、八进制、十进制、十六进制及 2-36 任意进制互转。无需注册,数据不离开浏览器,即时获取结果。