怎么用
- 把 JSON 粘贴到「输入 JSON」框里。可以是日志里的一行、一个完整的接口返回,也可以是一份配置文件。
- 选择缩进方式(2 个空格、4 个空格或制表符),以及是否按键名排序。
- 点格式化,或者按 Ctrl+Enter(Mac 上是 ⌘+Enter)。结果显示在右侧,下方会给出键的总数、嵌套层数和字节大小。
- 如果想去掉所有空白,点压缩。把 JSON 放进环境变量或网址参数之前,常常需要这一步。
- 如果输入不是合法的 JSON,红色提示框会告诉你第一个问题在第几行第几列,以及通常是什么原因造成的。点「在输入框中定位」就能跳到那个位置。
- 如果文本是大模型输出的、带着代码块或说明文字、用了单引号或注释的「差不多是 JSON」,点修复。结果区会显示修好并格式化后的 JSON,下面逐条列出改了什么;输入框里的原文不动。
- 复制结果,或者下载成 .json 文件。
超过 1 MB 的输入会放到后台线程里处理,页面不会卡住。你粘贴的内容不会离开当前页面。
工作原理
JSON 的语法由 RFC 8259 和 ECMA-404 定义,只允许六种值:对象、数组、双引号字符串、数字、true 或 false,以及 null。大家在 JavaScript 里习惯的其他写法,比如注释、单引号、末尾逗号、不加引号的键名、NaN、undefined,在 JSON 里都是非法的,所有严格的解析器都会拒绝。
为什么不直接用 JSON.parse
做 JSON 格式化最省事的办法,是先调用浏览器的 JSON.parse,再调用 JSON.stringify。但这样会悄悄改掉你的数据。JavaScript 的数字是 64 位浮点数,任何大于 2^53(9007199254740992)的整数都会丢精度:12345678901234567890 会变成 12345678901234567000。数据库主键、雪花算法生成的 ID、很多金额字段,恰好都在这个量级。JSON.parse 还会把 1.0 改写成 1,把 1e3 改写成 1000。
所以本工具用的是自己写的一个小解析器。它把数字当作原始文本读取,再原样写回,格式化后的每个数字都和输入逐字符一致。字符串会先解码再重新编码,所以像 \u00e9 这样的转义会变成字符 é,但值本身没有任何变化。
错误是怎么定位的
解析器从左到右读取文本,遇到第一个不该出现在那个位置的字符就停下,把这个位置换算成行号和列号(都从 1 开始)。这比某些浏览器只报一个字符偏移量更直观,也比 Safari 可靠,Safari 的报错里根本没有位置。之后工具会查看出错位置前后的字符来推测原因:逗号后面紧跟右括号,就是末尾逗号;本该是字符串开头的地方出现了单引号,就是引号用错了;依此类推。
修复:把「差不多是 JSON」变成 JSON
让大模型「只输出 JSON」,拿到的常常不是合法 JSON:外面包着 Markdown 代码块(三个反引号加 json),前面有一句「好的,下面是结果」;有的用了单引号或 Python 的 True、None;有的末尾多个逗号,或者两个属性之间漏了逗号;输出太长被截断时,括号和引号干脆没闭合。修复会在文本层面逐个改掉这些问题:去掉代码块和前后说明,删除注释,单引号改双引号并处理好内部的引号,给键名补引号,True、False、None 改成 true、false、null,NaN、Infinity、undefined 改成 null,删掉多余的逗号、补上漏掉的逗号,最后把没闭合的字符串和括号补齐(截断在冒号后面时,值填 null)。
修复不会动你的数据本身:数字仍然原样保留,字符串内容不变,字符串里的 // 也不会被当成注释。每一类修改都会列出来,你可以判断结果是不是你想要的。特别是被截断的文本,补齐后的 JSON 虽然合法,但后半截数据本来就没有,应当让模型重新生成完整的输出。
键名排序
排序会在每一层嵌套里,按 Unicode 码位对键名排序,这也是大多数编程语言的默认顺序。它适合用来比较两份 JSON:把两份都排序后,再用文本对比工具比较,键的顺序不同就不会再被当成差异。
示例
用 2 个空格缩进格式化 {"b":1,"a":[1,2]},键的原始顺序保持不变:
{
"b": 1,
"a": [
1,
2
]
}打开按键名排序后压缩 {"b":1,"a":2},得到 {"a":2,"b":1}。
大整数不会丢精度:{"n": 12345678901234567890} 压缩后是 {"n":12345678901234567890},而基于 JSON.parse 的工具会输出 12345678901234567000。同理,[1.0, 1e3, -0.10] 压缩后仍然是 [1.0,1e3,-0.10]。
一个出错的例子,最后一个属性后面多了逗号:
{
"a": 1,
}工具会报告第 3 行第 1 列,也就是右花括号的位置,并说明 JSON 不允许末尾逗号。输入 {a: 1} 会提示键名没有加引号;输入 {'a': 1} 会在第 2 列提示用了单引号。
统计信息:{"a":{"b":[1,{"c":2}]}} 一共有 3 个键,嵌套 4 层(最外层对象、a 下面的对象、b 下面的数组,以及数组里的对象)。
修复的例子。下面这段是大模型常见的输出:
```json
{'ok': True, 'items': [1, 2,], name: None}
```点修复后得到 {"ok": true, "items": [1, 2], "name": null},并列出做过的五类修改:去掉代码块围栏、单引号改双引号、Python 字面量改写、删除末尾逗号、给键名加引号。被截断的 {"items": [1, 2 会被补成 {"items": [1, 2]}。
局限
- 格式化和校验只接受严格的 JSON。 JSON5、JSONC(带注释的 JSON)和 JavaScript 对象字面量都会被报为错误,这样你才能知道严格的解析器会不会接受这段文本。需要转换时用「修复」,它覆盖上面列出的常见写法,但不是完整的 JSON5 解析器,例如十六进制数字和多行字符串不会被转换。
- 重复的键名。 RFC 8259 只说键名「应当」唯一,并没有禁止重复。同一个对象里某个键出现两次时,格式化结果保留最后一个值,这和 JSON.parse 的行为相同。如果重复键对你有意义,请在格式化之前先检查输入。
- 一次只报第一个错误。 解析在第一个问题处停止,改好之后再格式化一次,才能看到下一个。
- 嵌套过深。 嵌套超过 2000 层的文档会被拒绝处理,而不是让页面崩溃。
- 文件大小。 桌面浏览器处理几十 MB 没有问题;在手机上,这么大的文件可能会耗尽内存。
常见问题
把接口返回或 token 粘贴到这里安全吗?
格式化完全在浏览器里进行,不会带着你的输入发出任何网络请求,数据不会离开你的设备。和对待其他敏感信息一样,用完之后清空输入框即可。
为什么在 JavaScript 里能用的对象,这里提示「末尾逗号」?
JavaScript 的对象字面量允许最后一项后面带逗号,JSON 不允许。删掉对象或数组里最后那个逗号就能正常解析。
格式化会改变我的数字吗?
不会。数字按原样复制,包括大于 2^53 的整数、1.50 这样的末尾零,以及 1e3 这样的科学计数法写法。
ChatGPT 给的 JSON 解析报错怎么办?
点「修复」。它会去掉代码块和多余的说明文字,改正单引号、注释、末尾逗号和 Python 字面量,补齐被截断的括号,然后列出做了哪些修改。
能按 JSON Schema 校验吗?
暂时不能。本工具检查的是语法,也就是文本是不是合法的 JSON,不检查数据是否具备某个 Schema 要求的字段和类型。
格式化和压缩有什么区别?
格式化是加上换行和缩进,让人能看清结构;压缩是去掉所有多余的空白,让文本尽可能短。两者表示的数据完全相同。