JSON 工具
格式化、压缩、校验定位、键排序、转义与转 CSV 六个操作共用一份输入,改一处就能来回试
// 与 /* */)、单引号字符串、尾随逗号、NaN / Infinity、以及未加引号的对象键——这些都是 JSON5 或 JavaScript 对象的写法,不是 JSON 标准的一部分,解析器拒绝它们是正确行为。本页不提供"宽松模式":把非法输入偷偷"修好"会让你以为数据入库时也会通过,风险比报错大得多。
输入
粘贴 JSON,或点右侧按钮填入示例操作
格式化只做「重新排版」,不会改变值的类型,也不会给键排序——取消勾选「保留键的原始顺序」才会按键名重排(与「键排序」一致)。输出会给出字符数与行数。
结果
JSON 格式化、校验与转 CSV 里最容易踩的几件事
严格 JSON 的语法其实只有几页纸,但报错信息几乎没法读。RFC 8259 定义的 JSON 只有六种结构:对象 { }、数组 [ ]、字符串、数字、布尔值 true / false、以及 null。对象必须是「字符串键 + 冒号 + 值」,键必须用双引号;数组元素之间必须用逗号分隔,且最后一项后面不能再有逗号;字符串里除了少数字符外都不能直接出现控制字符。规范很短,可浏览器和多数语言抛出的错误却只是「Unexpected token } in JSON at position 42」——它只说第 42 个字符处出了意外,不告诉你第 42 个字符在第几行。本页做的就是把那个字符位置换算成「第 X 行第 Y 列」,同时在输入框里选中出错位置,让你一眼看到问题在哪。
尾随逗号、注释、单引号为什么必须报错。这是三个最常见的「看起来没问题」的写法:{ "a": 1, }(尾随逗号)、// 说明 或 /* 说明 */(注释)、{ 'a': 1 }(单引号)。它们全都是 JSON5 或 JavaScript 对象字面量的扩展,不是 JSON。JSON 的设计目标之一是「用极小的解析器就能正确读出」,因此它刻意不允许这些方便写法:注释会让同一份数据在没有注释语法的解析器里直接失败,尾随逗号会让「按逗号切分再逐段解析」的流式解析器多出一个空段。更麻烦的是,很多 JavaScript 环境(包括浏览器控制台、eval、以及 JavaScript 配置文件)会接受它们,于是同一段文本在本地「没问题」、发到服务端或换个语言解析时就炸。本页站在严格 JSON 这一边:宁可现在报错,也不要让它到生产环境才暴露。同样地,NaN 与 Infinity 在 JSON 里也不是合法值——需要表达「非数」时请用 null 或字符串。
格式化与压缩各自解决什么问题。格式化(缩进 2 空格 / 4 空格 / Tab)是为了给人看:代码评审、配置比对、排查层级关系。这里有一个容易被忽略的细节——格式化不应该改变键的顺序。有些工具会顺手把键按字母排序,看起来整齐,但「字段顺序」在不少场景下是有意义的(日志字段的自然阅读顺序、接口文档的示例顺序、以及对比两份文件的差异),悄悄重排会让 diff 噪点暴增。本页默认保留原始顺序,需要排序时请显式点「键排序」。压缩(minify)则是为了给机器传:去掉缩进与换行后体积通常能小两三成,放进请求体、环境变量或配置文件里更省事。注意压缩只删「结构上的空白」,字符串内部的空格与换行会被完整保留,所以压缩后解析出来的数据与压缩前完全等价。
转 CSV 的坑几乎全在「值里有逗号、引号、换行」和「编码」上。CSV 看起来很土,但它有一个所有表格软件都认的正式规范 RFC 4180。规范里真正的难点只有一条:当某个单元格里出现逗号、双引号或换行时,必须用双引号把整格包起来,并把格内的每个双引号写成两个。少了这一步,一个地址里的逗号就会把整行拆歪;多写一层引号又会多出真实的引号字符。另外三件事同样常见:① 表头要取所有对象的键的并集(接口返回的数组里,元素往往不是每个都有全部字段),缺字段的位置留空而不是错位;② Excel 在简体中文 Windows 上双击打开无 BOM 的 CSV 时会按本地代码页解读,中文直接乱码,因此本页默认在文件开头写入 UTF-8 BOM;③ 数字与文本的界线——CSV 没有类型,007 与 7 到了表格里都会被当数字,需要保留前导零时得在导出前把它变成带引号的文本。本页严格按 RFC 4180 处理这三类字符,嵌套对象与数组会写成一格紧凑 JSON,而不是被压平成多列(压平会丢失结构与层级信息,宁可让你再处理一次)。
为什么不上传到服务器。JSON 是最容易夹带敏感内容的格式:接口返回里可能有 token、数据库配置、内网地址、用户的手机号与身份证号,运维配置文件里往往还有密钥。把这样一段文本粘进一个在线格式化工具,如果它在服务端解析,你就等于把凭证复制了一份给第三方——而且很多站点的"历史记录"会把它留在数据库里。本工具的全部逻辑(解析、定位、排序、转义、转 CSV)都是运行在你浏览器内的一段纯 JavaScript 函数,写在页面的 PURE 区块里,可以用开发者工具的 Sources 面板逐行读完;整页没有任何提交请求,也没有写入 localStorage 或 cookie 的历史记录。断网状态下刷新页面,它照样能用。
常见问题
position 是「从第 0 个字符数起的字符位置」(V8 里按 UTF-16 码元计数:中文与全角标点算 1 个,emoji 与其它增补平面字符算 2 个),不等于行号。本页把它换算成第几行第几列,并给出一小段上下文,比如「第 3 行第 15 列附近:"age": ,」。同时在输入框里用选区选中那个位置并自动滚动过去。如果某个浏览器在错误信息里不带 position,本页会如实写「无法定位,但这不是合法 JSON」,不会编一个位置给你。
因为那些工具用的是「宽松解析」(JSON5、JSONC 或直接 eval)。它们很方便,但结果是同一段文本在 Python 的 json.loads、Java 的 Jackson、Go 的 encoding/json 里都会失败——数据库写入、网关转发、消息队列消费都会在那一刻中断。本页坚持严格 RFC 8259,就是为了让你在粘贴的这一刻发现它,而不是上线之后。顺带一提:VS Code 的 settings.json、TypeScript 的 tsconfig.json 之所以允许注释,是因为它们读的是 JSONC(JSON with Comments),不是标准 JSON。
这取决于你的输入本身是否已经在 JavaScript 的精度边界之外。JSON.parse 会把数字解析成 IEEE 754 双精度浮点,因此超过 2 的 53 次方的整数(例如某些雪花算法 ID、19 位的订单号)在解析那一刻就已经失真,再格式化出来自然也是失真的,本页同样无法还原。这类场景请让接口把 ID 当字符串返回。另外,格式化与压缩只是重新排版,不会把 1.0 变成 1 之外的其它值,也不会改变键的顺序(除非你显式点了「键排序」)。
CSV 是二维表格,一行是一条记录,所以需要「一组结构相同的记录」。顶层是对象时(例如 { "total": 3, "rows": [ ... ] }),本页会明确提示不支持,而不会自作主张地猜你想导出哪个字段——猜错了你未必看得出来。正确做法是先把要导出的数组取出来再粘贴进来。同理,如果数组里混有数字或字符串,或者所有元素都不是对象,也会被拒绝并说明原因。
这是 Excel 的自动类型推断,不是 CSV 本身的问题:18 位数字会被转成 1.2E+17,2024-01-05 这类文本会被识别成日期。CSV 规范里没有「类型」概念,所以本工具无法阻止 Excel 这么做。稳妥的做法是:需要保持原样的长数字(订单号、身份证号)在导出后于 Excel 里把该列设置为「文本」再重新导入(或用「数据 → 从文本/CSV」导入向导,并在导入时把该列指定为文本)。本页默认带 UTF-8 BOM 只是解决中文乱码,不解决类型推断。