/* Auto ads 与同意门控都依赖这里的 client meta —— 缺了它 consent.js 的 loadAds() 会直接 return,本页永远不加载 AdSense(第 30 轮实测发现中文 324 页全缺) */
aibox

JSON 格式化 / 校验

粘进来就能按 2 个空格、4 个空格或 Tab 重新排版,也可以一键压成一行;如果它根本不是合法 JSON,这里会给出出错的行号和列号,以及人话的原因。所有解析都在你的浏览器里完成,粘进来的内容不会上传。

接口返回、配置文件、日志里的一段、手写的片段都可以。 短内容边打字边校验;长内容留到你点按钮时再算。在输入框里按 Ctrl/⌘ + Enter 等于点「格式化」。

顶层类型
对象里的键总数
嵌套深度
输入字符数
输入字节数(UTF-8)
输入行数

你在上面输入的内容不会发给我们:解析、格式化、压缩全部在这个页面里完成。详见 隐私说明

怎么用

  1. 把 JSON 粘进框里。接口返回、配置文件、日志片段、手写的内容都行。短内容会边打字边校验; 长内容留到你按按钮时再算 —— 每敲一个字就重新解析一份大文件,输入会明显发卡。
  2. 选缩进,点「格式化」。2 个空格是最常见的约定,也是 diff 视图期望的形式;4 个空格在 Java、.NET 项目里常见;Tab 让文件更小,而且每个读者可以用自己的宽度显示。想反着来就点「压缩成一行」: 去掉全部多余空白,只留一行。
  3. 看结果,然后复制或下载。下面的统计告诉你解析器实际看到了什么:顶层是什么类型、所有对象里 一共多少个键、结构有多深、按字符和 UTF-8 字节各有多大。

如果不是合法 JSON,你不会得到任何结果,只会得到出错的行、列和一句人话原因。这是刻意的: 半个格式化结果看起来像是成功了。

报错,但不替你修

不少格式化工具会悄悄把问题抹平:删掉多出来的逗号、把单引号换成双引号、删掉注释。这样得到的文件在你的 编辑器里看着完全正常,发给你要发给的那个程序却照样失败 —— 而且真正的问题被藏起来了:这段文字本来就不是 JSON。

这个工具不改写你的输入。解析失败时你会拿到位置和原因,而"这些数据本来想表达什么"这件事留给你判断。 下面这七类写法覆盖了绝大多数情况:

你粘进来的写法JSON 要求通常来自哪里
{"a": 1,}}] 前面不能有逗号手改过的配置、JS 对象字面量
{'a': 1}键和字符串都用双引号Python 字典、JavaScript 字面量
{a: 1}键必须是加引号的字符串JS 简写、YAML
// 说明JSON 没有任何注释语法JSONC、tsconfig、文档里的示例
NaNInfinityundefined只有数字、字符串、布尔、null、数组、对象把 JS 的值直接序列化出来
010x1F+5不能有前导零、十六进制、正号从代码里复制的数字
{"a": 1 "b": 2}两项之间要有逗号手改、或者粘贴被截断

其中两类值得多说一句,因为报错的位置都不是你真正写错的那个字符:少了逗号时报的是"本该有逗号的那个 位置",括号没闭合时报在文本结束之后 —— 文件就是在这里断掉的。这两种情况下位置都是对的,它标的是解析器 无法继续的那一刻。

行号和列号是怎么定出来的

同一个错误,三个浏览器引擎的说法完全不同:Chrome 报字符位置外加行列,Firefox 只报行列,Safari 常常 什么都不报。所以这个工具从不照抄那句报错 —— 引擎给了字符位置就用它,没给就用自己那个严格扫描器逐字 定位,再按你粘进来的原文算出行列。具体有三条规则:

  • 行按换行符数。内容相同的 CRLF 文件和 LF 文件会报出同一行同一列 —— 否则同一份文档在 Windows 和 macOS 上看起来会是两个不同的错误。
  • 列按字符数,不按字节也不按 UTF-16 码元。一个汉字、一个 emoji 都算一列,跟编辑器里看到的一致。
  • 都定位不到时明说不知道。不会为了显得权威而印一个编出来的位置。

这件事比听上去重要:位置是语法错误里唯一能照着动手的信息,没有它,你就只能在一份四千行的数据里用眼睛找。

有两种情况,格式化会改变你的数据

格式化本该是无损的,对格式良好的 JSON 也确实如此。只有两个例外,本工具都会明确报出来, 而不是让你以后自己发现。

重复的键

JSON 的文法允许一个对象里出现两次同一个键,但没规定这意味着什么。包括你浏览器在内的每个 JavaScript 引擎都保留最后一个值、丢掉前面的。所以 {"a": 1, "a": 2} 格式化后是 {"a": 2},第一个值没有了。本工具会把发现重复的路径列出来 —— 这正是"重新排版"与 "改了文件"之间的区别。

超出精确范围的整数

JavaScript 只有一种数字类型:64 位双精度浮点。能精确表示的整数上限是 9007199254740991(253 − 1)。 20 位的订单号、雪花 ID 在被读到之前就已经被四舍五入过:12345678901234567890 会变成 12345678901234567000。本工具会数出超过这个范围的整数并逐个点名,因为一个被四舍五入过的 标识,出事的地方往往不是编辑器而是几天后的线上。

这两种情况的解法都在你那边:如果本来想留的是前面那个重复值,或者这个 ID 必须一字不差, 请改用保留数字字面量的工具 —— 例如命令行的 jq,或者把大数字当字符串读的解析器。

大文件、长粘贴,与浏览器这一个标签页

解析和重新序列化跟页面绘制跑在同一个线程上,所以过了某个量级,格式化工具带来的就不再是方便, 而是一个看起来像卡死的标签页。下面三条限制都是从这件事推出来的,而且都是明说而不是悄悄执行:

  • 200 万个字符是硬上限。超过就直接拒绝并解释原因,因为那种卡顿和崩溃在用户看来没有区别。
  • 超过 30 万个字符的粘贴会先显示"正在处理",计算放到下一个事件循环节拍里执行, 这样界面先画出来再干活。低于这个量级的工作在一帧内就结束了,提示只会一闪而过,反而干扰。
  • 嵌套极深的 JSON可能合法却写不出来:浏览器原生的序列化是递归的,大约五千层就会把调用栈用尽。 本工具会识别这种情况并告诉你"数据没问题,是工具的限制"—— 这才是诚实的说法,也正是这种时候该换命令行。

这些限制都不影响正确性:400KB 的数据和 4 字节的数据,格式化的准确程度完全一样。

有什么东西离开了这个页面

没有。不上传、不请求我们的服务器、不给你的数据挂任何统计事件、不做任何存储:这一页只引用了一个 小模块的纯函数,之后全在本地算。关掉标签页,你粘进来的 JSON 就没了。

但这不等于任何内容都可以往里粘。如果你用的是共用或受管理的电脑,剪贴板、下载目录和浏览器自己的内存 都不在这个页面能管的范围内;而且任何还在生效的密钥,粘到哪里都还是有效的。这个工具只负责告诉你它看到了 什么,你带在身上的东西还得你自己负责。

常见问题

为什么这段 JSON 在 JavaScript 里能用,到这里就报错?
因为 JavaScript 的对象字面量不是 JSON。JS 允许键不加引号、允许单引号、允许最后多一个逗号、允许 // 注释、允许 NaN 和 undefined —— JSON 一个都不允许,JSON.parse 全部拒绝。本工具按 JSON 的规矩来:多一个逗号就报到它的行列位置,不会替你删掉。如果这段文字是从 .js 文件里拷出来的,这个差别通常就是全部原因。
它报的行号列号可信吗?
行号列号是根据出错字符的偏移量算出来的,不是照抄浏览器的报错文字 —— 三个引擎对同一个错误的说法完全不同:Chrome 给字符位置,Firefox 只给行列,Safari 常常什么都不给。浏览器没给位置时,本工具用自己的严格扫描器定位。行按换行符数,CRLF 与 LF 得到同样的行列,中文和 emoji 各算一列,所以在编辑器里对着数能对上。两边都定位不到时,它会直接说位置未知,不会编一个数字出来。
格式化和校验是一回事吗?
不是,分开看更有用。校验只回答一个问题:这段文本是不是合法 JSON;格式化是在"它是合法的"这个前提下重新排版。本工具一定先解析再输出,所以看到格式化结果就等于确认了解析通过。也正因为这个顺序,这里没有"自动修复"按钮:把多出来的逗号悄悄删掉,只会让本工具认可一份你真正要发给别人的程序仍然会拒绝的文本。
重复的键会怎么处理?
保留最后一个,这是所有 JavaScript 引擎里 JSON.parse 的行为,属于语言规则,不是这里的开关。本工具不假装没有这回事:发现重复键就会把它们列出来,让你判断重复是不是你想要的。如果本来想留的是前面那个值,那么"格式化"这一步其实已经改动了你的数据 —— 那条提示是唯一会告诉你这件事的地方。
为什么大整数 ID 格式化之后就变了?
因为 JavaScript 只有一种数字类型:64 位双精度浮点,能精确表示的整数上限是 9007199254740991。像 12345678901234567890 这样的订单号,一进解析就已经变成 12345678901234567000。本工具会数出超出这个范围的整数并单独提示,而不是把一个四舍五入过的值当成结果交给你。如果整份数据都是靠大整数 ID 串起来的,请改用能保留数字字面量的工具。
能处理多大的文件?
上限 200 万个字符(大约 2MB 文本)。超过就直接拒绝并说明原因,而不是让标签页卡住 —— 解析和重新序列化跟页面绘制跑在同一个线程上。超过 30 万个字符的输入会先显示"正在处理",让你知道它确实动了。文件比上限还大就切开处理,或者干脆用命令行工具,那种体量本来也更适合命令行。

不含任何数据。这一页没有 schema、没有示例数据表、没有查询表 —— 它显示的每一个字符都 来自你粘进来的内容。它唯一的判据就是 JSON 文法本身。