格式化JSON听起来像是工具能做的最简单的事情:添加一些空格和换行符,
让人类可以阅读。大多数格式化工具正是这样做的,通过调用JSON.parse
然后调用带缩进参数的JSON.stringify。这个往返过程对您手写的JSON
有效,但对从其他地方获取的JSON会悄悄损坏。
往返过程导致的两个bug
JSON.parse将每个数字转换为JavaScript double。double无法在
Number.MAX_SAFE_INTEGER(即9007199254740991)之后精确容纳每个
整数。雪花ID、数据库主键或纳秒级时间戳很容易超过这个限制,一旦
超过,重新序列化解析值会改变数字。12345678901234567890会变成
12345678901234567000。在下游某处ID出错之前,没有人会注意到。
相同的往返过程还会重新排序看起来像数字的对象键,因为
JSON.stringify以特定顺序遍历JavaScript对象自身的可枚举键:整数
类键优先,升序排列,然后其他所有键按插入顺序排列。写为
{"2": "b", "1": "a"}的文档会变成{"1": "a", "2": "b"},
即使每个值都保留下来,这也是一个不同的文档。
JSON格式化工具的做法
此工具从不调用JSON.parse。它将您的文档标记化,根据RFC 8259
验证令牌流,然后从这些令牌重新打印。数字作为您写入的精确字符
复制,而不是通过double重新编码。键保持在您放置的位置。粘贴
{"2":"second","1":"first","id":12345678901234567890,"note":"line1\nline2"}
然后按格式化按钮返回:
{
"2": "second",
"1": "first",
"id": 12345678901234567890,
"note": "line1\nline2"
}
"2"仍然在"1"前面,二十位数字的id完全按原样返回。
只有空白字符发生了变化。
阅读错误
如果文档不是有效的JSON,工具会在错误栏中标记有问题的行,并命名 实际错误,而不是引用它卡住的令牌。闭合大括号前的尾随逗号会作为 尾随逗号报告,在逗号所在的行上,而不是在文件末尾(简单解析器会 在那里放弃的地方)。
格式化 vs 压缩
两个按钮执行相同的从令牌重新打印;只有空白字符不同。格式化添加 换行符和您选择的缩进宽度(2个空格、4个空格或制表符)。压缩删除 JSON不需要的每个空格、制表符和换行符。两者都不会更改值,因此可以 随时按任意次数,或在两者之间切换而无需重新粘贴。
在具有长ID或数字键配置文件的文档上尝试它,并与通过JSON.parse
的格式化工具进行比较。差异立即显现。