JSON 格式化与校验

全球通用工具

一段 JSON 只要被压成四千个字符的一行,就没法读了。这个页面把它排版展开、压缩回一行、按键排序以便对比两个版本、统计里面究竟有什么,并在出错时做最要紧的那件事:说清楚错在哪里。

严格 JSON,也就是 JSON.parse 接受的那种:字符串和键都用双引号,没有注释,没有尾随逗号。几乎构成所有报错的四类常见错误,会在下方单独给出提示。

只改空白:两个空格是大多数风格指南和代码评审默认的样子,制表符是老编辑器显示的宽度,压缩则去掉全部可选空白、文档依然合法。

排序是为了阅读,也为了对比两份文档;无论选哪一项,数组都保持原有顺序,因为顺序本身就是数据。

留空则使用「formatted.json」。

边输入边更新。所有计算都在你的浏览器里完成,数据不会离开本机。

有效的 JSON:顶层为对象

15 行

缩进方式:2 个空格。内容没有被改写:输出重新解析后与输入完全相同。

输入
164 B
输出
196 B
键
8
嵌套层级
4

格式化后的 JSON

{
  "name": "danfio",
  "tools": [
    {
      "slug": "json-formatter",
      "stars": 4
    },
    {
      "slug": "base64-encoder",
      "stars": 3
    }
  ],
  "free": true,
  "notes": null
}

可以复制,也可以下载成文件。格式化只改变空白;排序只改变对象内部键的顺序。

这些数字没有说明的事

  • 3 个对象、1 个数组、3 个字符串、2 个数字、1 个布尔值、1 个 null。
  • JSON 没有整数类型:数字是双精度浮点数,所以超过约十五位的标识符(推文 id、数据库主键)在这个页面看到它之前就可能已经丢了精度。这是格式的问题,不是这个工具的问题 —— 这类值请用字符串承载。
  • 同一个对象里的重复键在 JSON 里不算错误:以最后一个为准,等到有东西能数它们的时候,前面的值早已不在。
文本是在这个浏览器标签页里读取、格式化并统计的。页面背后没有任何请求,所以把令牌、私有配置或客户返回的数据粘进来,和粘进记事本没有区别。

解析用的是浏览器自带的 JSON.parse,也就是生产环境读取这份文件的同一个解析器,所以不存在「这里能过、那里过不了」:这个页面判为有效,最严格的解析器也会认同。文本不会上传,除了空白之外不会被改写。

关于这个工具

在调用栈、API 响应或配置文件里,JSON 一旦变成一整行就没法读了。这个页面把它排版展开、压缩回一行、按键排序以便对比两个版本、统计里面有什么,并在出错时指出确切的行和列。

校验用的是浏览器自带的 JSON 读取能力,与生产环境读这份文件的是同一套规则,所以这个页面接受的文档,最严格的读取方式也接受。没有账号,也没有后端:文本在当前标签页里完成校验与重排,不会被存储。统计数字来自值本身,不是文本。

格式化只改变空白与可排序的键顺序,别的都不动,输出读回来仍是同一批值。重复键会被悄悄折叠成最后一个,这是格式本身的静默失败。这个页面负责重排与校验,不会替你修复 JSON。

它是怎么工作的

严格 JSON,以及几乎所有报错都源于的四类写法

JSON 只有一套规则,没有扩展语法:每个字符串、每个键都必须用双引号,没有注释,没有尾随逗号,也写不出 NaN、Infinity、undefined —— 那些是 JavaScript 的值,JSON 没有对应的写法。一段看起来很像 JSON 的 JavaScript 对象字面量,通常并不是 JSON:配置文件解析失败,最常见的原因就是它。

所以文本被拒绝时,这个页面不只报错,还会点名错在哪:右括号前多了逗号,会提示 JSON 不允许在最后一项后面加逗号;用了单引号,会提示 JSON 字符串必须用双引号;键没加引号,会提示 JSON 的键必须是字符串;出现 // 或 /* */,会明确指出那是注释。这四类,加上冒号后面缺值,几乎覆盖了所有人粘贴过的坏文档。

严格 JSON 唯一不会报错的坑,是同一个对象里出现重复键:以最后一个为准,前面的值悄悄消失 —— 等到有东西能数它的时候,它早就不在解析结果里了。这是格式本身的行为;也正因为它是静默失败而不是大声报错,才格外容易坑人。

格式化和压缩到底改了什么

格式化只改空白:标记之间的缩进、用几个空格缩进,以及要不要缩进。压缩是同一个操作把缩进设为零,所以压缩后的文档并没有被「压缩」—— 数据一个字节没变,只是去掉了空白。把输出读回来,值仍与输入相同:格式化若动了别的东西,一眼就能看出来。

排序是唯一一个会让文本肉眼可见地变动的选项,而且只动对象内部的键顺序。数组永远保持原来的顺序,因为数组是序列,顺序本身就是数据 —— 排序数组是缺陷,不是功能。

这两件事合起来,才让两份文档变得可比:两份都格式化、都按键排序,再逐行对比,看到的是真正的差异,而不是某个写文件的工具恰好按什么顺序排列键。

数字从哪里来,以及 JSON 装不下的两样东西

头部的统计是从解析后的值里数出来的,不是数文本:对象、数组、字符串、数字、布尔值、null 各有多少个,嵌套有多深,总共多少个键。字节按 UTF-8 计算,所以一份满是 emoji 的文档,字节数会多于字符数。

JSON 没有整数类型 —— 所有数字都受浏览器固定精度限制 —— 所以超过约十五位有效数字的标识符,一解析就可能丢精度,而且这在任何读取 JSON 的工具里都一样,不止是这个页面。推文的 id、数据库主键、银行卡号,正因如此都该当成字符串。金额同理:0.1 + 0.2 这个著名例子,就是货币金额应该用字符串或最小货币单位的整数传输的原因。

JSON 装不下的另一样东西是注释:根本没有写法。这也是 JSON5、JSONC、YAML、TOML 这些需要注释的配置格式存在的原因 —— 也正因为如此,这个页面不会悄悄帮你把注释删掉:一个接受「差不多是 JSON」的格式化工具,会把「差不多是 JSON」送进那些将由严格读取器打开的文件里。

示例

示例使用页面自带的默认输入,只改设置;下面的结果与你在页面上看到的完全一致。

一段 API 响应,变得可读

排版方式: 2 个空格(最常用)

有效的 JSON:顶层为对象

15 行

缩进方式:2 个空格。内容没有被改写:输出重新解析后与输入完全相同。

输入: 164 B · 输出: 196 B · 键: 8 · 嵌套层级: 4

两个空格是几乎所有风格指南最后都会选的约定,也是既不牺牲可读性、又不让文档膨胀的设置。输出读回来之后,与输入的值完全一致。

同一份文档,压缩后用于传输

排版方式: 完全不缩进,压缩成一行

有效的 JSON:顶层为对象

124 个字符,单行

已压缩:标记之间的空白全部去掉,值本身没有任何改动。

输入: 164 B · 输出: 124 B · 键: 8 · 嵌套层级: 4

压缩只去掉标记之间的空白,别的都不动 —— 文档里字符串内部原有的空格一个都不会少。压缩后的文件传起来更小、读起来更难,所以没有人会去评审它。

两份配置文件,排成可以对比的顺序

排版方式: 2 个空格(最常用) · 对象键顺序: 按键名 A–Z 排序,每一层都排

有效的 JSON:顶层为对象

15 行

缩进方式:2 个空格,键已按 A–Z 排序。内容没有被改写:输出重新解析后与输入完全相同。

输入: 164 B · 输出: 196 B · 键: 8 · 嵌套层级: 4

在每一层都给键排序,才让 diff 变得可用:真正的差异会跳出来,而不是埋在键顺序不同里。数组永远不重排,因为它们的顺序就是数据。

常见问题

我的 JSON 会被上传吗?

不会。文本由当前标签页里的 JavaScript 读取,交给浏览器自带的 JSON 读取能力处理,并在本地排版;下载文件也是本地生成的 blob。这个页面背后没有任何接口 —— 所以把访问令牌、私有配置或客户返回的数据粘进来,和你把它粘进记事本没有区别。API 密钥、凭证和个人数据正是人们最常粘进格式化工具的东西,这也正是这个工具没有服务端的原因。

为什么带注释的配置文件会被拒绝?

因为它其实是 JSON5 或 JSONC,不是 JSON:注释是不少工具接受的超集,而 JSON 格式本身不接受。在这里放行才是危险的选择 —— 文件在这个页面能过,到了生产环境里读它的那个东西就过不去。要么在源头把注释去掉,要么改用那个格式自己的工具;报错信息会点名是注释,让你知道问题不在更隐蔽的地方。

压缩到底去掉了什么?

标记之间的空白:缩进、换行,以及冒号和逗号周围的空格。它动不了字符串内部,所以一条带空格的提示信息,一个空格都不会少 —— 引号里的空白是数据。压缩通常能省下排版文档 20–40% 的体积,含义一点不变。

为什么格式化之后我那个大数字变了?

因为 JSON 的数字受浏览器固定精度限制,只能精确表示约十五位有效数字。十六七位的标识符回来时可能已经被四舍五入,而这在任何读取 JSON 的工具里都会发生,包括你后端用的那个。要修的地方在源头:标识符和金额都以字符串发送。

数组里的内容也能排序吗?

不能,任何尊重这个格式的工具都不会这么做:数组是序列,顺序承载含义 —— 一串步骤、一组坐标、一次查询的结果。能排序的是对象内部的键,它们为查找而存在,不以顺序为意义;这个选项在每一层做的正是这件事。

我的重复键去哪儿了?

读取留下了最后一个,所有读取 JSON 的工具都这样。同一个对象里出现两个一样的键,在格式上不算错误,所以没有任何东西会报错;前面那个值就是单纯地不在了。如果一份文档是合并对象拼出来的,这正是一口吞掉值的机制,而唯一能看见它的方式,是把输入和读取后的结果放在一起对比。

可以用它对比两份文档吗?

可以间接地做:两份都格式化并开启键排序,然后用普通的文本对比,看到的就是真正的差异,而不是巧合的键顺序。内置的 diff 不在这个页面的范围里,而一个懂 JSON 的 diff(理解子树移动,而不是数行)是完全另一个工具,所以这里的说法只说自己是什么。

它会按 JSON Schema 校验吗?

不会:这里检查的是语法,也就是「这到底是不是 JSON」,而不是结构,也就是「这是不是我以为的那份 JSON」。Schema 校验需要 schema 本身,报的也是完全另一类问题(缺了必填字段、类型不对、本该是数字的地方写了字符串)。做不好还不如不做。

资料来源与统计口径

  • 格式就是 RFC 8259 与 ECMA-404 定义的 JSON:键与字符串用双引号,没有注释,也没有尾随逗号。
  • 页面只接受严格合法的 JSON:差一点的文档会带着行号和提示被指出来,而不是被悄悄改好。
  • 数字精度取决于浏览器(约 15 位有效数字);文档不会离开这个标签页,也不会上传。

最近复核于 2026-09-16.

本页在您的浏览器本地运行,请保留原文件备份;不涉及财务建议。 阅读完整免责声明。