JSON Diff 对比
在浏览器中即时对比两份 JSON。Side-by-Side 高亮 + RFC 6902 JSON Patch 输出,一键忽略 timestamps、IDs 等噪音字段。100% 隐私保护,零上传。
高级选项
什么是 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 转 YAML、YAML 转 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
粘贴两份 JSON
把原始(左)和修改后(右)JSON 粘贴进来。边输入边渲染 live diff;大输入(>200 KB)会切换到手动 Diff 按钮。
- 2
过滤噪音
点预设(Timestamps / IDs / Trace)或粘贴 Extended JSON Pointer 模式到 Ignore paths,去掉无关字段。
- 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 却显示满屏变化?
如何在 JSON diff 中忽略 timestamps 和 IDs?
JSON Patch 和 visual diff 有什么区别?
JSON diff 把 null 和缺失的 key 视为相同吗?
数组按什么对比 —— index 还是 key?
可以导出为 RFC 6902 JSON Patch 吗?
JSON Patch 和 JSON Merge Patch (RFC 7396) 是同一个吗?
如何对比超过 10 MB 的大 JSON 文件?
本工具会把 JSON 上传到服务器吗?
为什么 42 和 "42" 在 diff 中不一样?
可以 diff 含注释(JSONC)或尾逗号的 JSON 吗?
如何按 id 这样的 key 对比嵌套对象数组?
Diff 能处理浮点精度(0.1 + 0.2)吗?
相关工具
查看所有工具 →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 任意进制互转。无需注册,数据不离开浏览器,即时获取结果。