ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

浏览器常驻JSON查看器:JSON-handle接口调试提效与避坑

浏览器常驻JSON查看器:JSON-handle接口调试提效与避坑

1. 为什么值得在浏览器里常驻一个 JSON 查看器

下午三点,联调群里甩过来一个接口地址,附一句"返回的数据不对,你自己看看"。地址往地址栏一粘,回车,屏幕上出现的是一整片挤在一起的字符:大括号套中括号,中括号里再套大括号,中间夹着一长串订单号和时间戳,全是等宽字体,翻了三屏还没找到那个关键的 status 字段。想按 Ctrl+F 搜一下,搜出来十几次,还得一个一个数层级、数括号,判断这到底是第几个数组元素里的 status。

这种场景做后端、前端、测试的人都不陌生。JSON 本身是个好东西,结构清晰、机器友好,偏偏浏览器默认的渲染方式对人极不友好——它把 JSON 当成纯文本,原样吐给你看,连换行都不肯加。这时候就需要一个东西,在你打开接口地址的瞬间,把这一坨文本接管过去,重新画成一棵可以点开、可以收起、可以搜索、可以复制路径的树。JSON-handle 就是干这个的,一款跑在 Chrome 浏览器上的扩展,装上之后不需要任何额外操作,只要你直接打开一个返回 JSON 的地址,页面就会被它接管,原始的字符流变成带缩进、带颜色、带折叠箭头的结构化视图。

它的价值不在于"炫酷",而在于把接口调试里最耗时间的那几个动作压缩到了几乎为零:找字段从"数括号"变成"点两下",确认层级从"肉眼数数组下标"变成"看路径栏",转述某个值从"截长图发给同事"变成"复制一行 JSON Path"。适合看这篇内容的人范围也挺宽:前端同学调接口、后端同学自测返回体、测试同学核对字段、做数据分析的临时扒一下开放接口、运维排查服务健康检查的返回,甚至写文档的要把接口响应整理成示例,都能用上。哪怕你是刚入门、只会用浏览器打开网页的阶段,装完也能立刻受益,不需要理解什么原理。

不过工具终究是工具,用得顺手和用得明白是两回事。下面我按自己这几年反复安装、卸载、再装回来的经验,把这个插件的选型逻辑、界面构成、核心操作、容易踩的坑,以及 POST 接口这种它天生不支持的场景怎么绕过去,一条一条拆开讲。

2. 方案选型:为什么最后留下了浏览器扩展

2.1 接口调试里真正耗时的三个动作

先把这个需求拆细一点,才能判断哪类工具合适。看一个 JSON 响应,表面上只是"看",实际上里面藏着三个动作,而且每个动作的耗时方式完全不同。

第一个是定位。你要找的那个字段,可能藏在四层嵌套里,前面还有三个数组。原始文本里它和一堆同名 key 混在一起,光标放进去都得靠运气。这个动作的耗时随嵌套深度线性增长,嵌套越深越难受。

第二个是确认层级。找到了字段,还得确认它属于哪个对象、是哪个数组的第几项。原始文本里没有路径概念,你得从头数开括号,数到大括号、中括号的配对关系,才能确定data.list[3].orderNo这个坐标。这个动作最容易出错,数错一层,整个判断就歪了。

第三个是转述。要跟同事说"你看这个字段不对",得截图,或者手工拼一段 JSON 片段粘过去。截图没人愿意看,手工拼又容易漏掉外围结构,对方拿到片段还是不知道具体位置。

一个趁手的工具,本质上就是把这三个动作各压缩一个数量级。定位从"翻页找"变成"搜索框一敲",层级从"数括号"变成"读路径栏",转述从"截图"变成"复制路径"。剩下的所有功能,都是围绕这三件事的锦上添花。

2.2 四类工具的实际对比

市面上能看 JSON 的东西不少,我把它们按"介入成本"和"数据流向"两个维度摆一摆,你就明白为什么浏览器扩展这个位置特别稳。

方案类型典型形态介入成本数据流向适合场景
在线格式化网站网页版格式化器复制粘贴,来回切窗口数据上传到对方服务器完全脱敏的示例数据
接口调试客户端桌面端接口工具要建项目、导入环境、配变量数据留在本机需要长期维护的接口集合
编辑器插件IDE 内格式化要落盘成文件再打开数据留在本机已经存成文件的报文
浏览器扩展直接接管页面装一次,之后零操作数据留在本机临时看一眼、快速定位

关键差别在第一行和第四行。在线网站最省事,但你把响应体贴进去的那一刻,数据就出去了。开发环境的数据无所谓,可一旦是带用户手机号、带订单金额、带内部标识的返回体,这么做就是在给自己埋雷。有些团队的安全规范里明确禁止把业务数据粘贴到第三方站点,这不是小题大做,是实实在在的风险。

接口调试客户端功能最全,可它重。为了看一眼某个字段,你得先打开客户端、找到对应的接口、切到那个环境、点发送,一整套流程下来,黄花菜都凉了。它适合的是"我要反复调这个接口",不是"我就想确认一下这个字段返回得对不对"。

编辑器插件的问题是要落盘。响应体得先存成.json文件,再用编辑器打开,多了一步复制粘贴,而且文件还得记得删,不然工作区里堆一堆response(3).json。

浏览器扩展刚好卡在中间:装一次,之后地址栏一敲就有,数据不出本机,零操作成本。JSON-handle 在这个位置上的优势不是功能最多,而是"打开了就自动生效"这件事——它不需要你点击任何按钮,只要你访问的是一个返回 JSON 的地址,页面渲染阶段它就把原始文本接过来了。

2.3 它做什么,以及明确不做什么

这一点得说清楚,免得期待错位。JSON-handle 的定位是"查看器 + 轻量编辑器",不是接口管理工具。

它做的是:把文本渲染成树、折叠展开、搜索定位、显示 JSON Path、就地修改值、格式化与压缩互转、复制节点、导出文件、切换原始文本视图。这些都在一个页面内完成,不需要联网,不需要登录。

它不做的是:不发请求、不管接口集合、不存环境变量、不做断言校验、不做 Mock、不做性能压测。你在树里改了一个值,它只是改了你眼前这份数据的展示,点"发送"也顶多是把改完的内容当成本地文件重新加载一遍,它不会把修改回写到后端。很多人第一次用会误以为这是个接口编辑器,改完点发送,刷新页面发现数据没变,然后怀疑是插件坏了。不是坏了,是它压根没这个设计。

3. 安装、启用与界面构成

3.1 装上并固定到工具栏

在 Chrome 浏览器的扩展商店里搜JSON-handle,找到对应的条目添加即可。装完之后浏览器右上角会出现一个拼图形状的图标,点开能看到已安装的扩展列表,把 JSON-handle 后面那个图钉点亮,它就常驻在工具栏上了。

固定这一步别省。虽然插件对 JSON 页面的接管是自动的,不需要你点图标,但工具栏上有入口意味着你能随时点开它的设置页、查看版本、临时开关,出问题时排查起来方便得多。我第一次装的时候没固定,过两天想找设置在哪,翻了半天扩展列表。

有一点要提前说:不少公司的办公电脑装了终端管控,扩展商店可能打不开或者装不上。这种情况别硬折腾,走内部的软件白名单流程,让 IT 把扩展 ID 加进去。自己想办法绕过管控,轻则被安全软件告警,重则违反内部规定,不值当。

3.2 生效条件:为什么有些 JSON 它就是不管

这是新用户最常问的问题:"我这个地址明明返回的是 JSON,怎么还是原来的样子?"插件没坏,是生效条件没满足。它靠的是在页面加载阶段判断响应的内容类型,只有满足条件才会接管渲染。

条件说明不满足时的表现
顶层导航地址栏直接打开,或链接跳转过去的整页页面内嵌的 iframe 里可能不生效
内容类型为 JSONapplication/json、text/json等返回text/plain就按纯文本显示
非二进制响应响应体是文本而非流responseType为 blob 时不接管
未被页面策略拦截页面没有禁用内联注入控制台会有相关报错

最常见的是第二条。有些后端框架图省事,把 JSON 响应的内容类型写成了text/html或者text/plain,浏览器就不认为这是 JSON,插件也就没理由插手。这时候打开开发者工具的 Network 面板看一眼响应头,Content-Type 是什么一目了然。如果是团队的接口,建议让后端改对,这本来就是该改的;如果改不了,那就只能走后面讲的"本地文件"绕行方案。

3.3 界面上的三个区域

打开一个 JSON 地址之后,页面大致分成三块,从上到下。

顶部工具条:左边一般是格式切换(美化 / 压缩)、视图切换(树形 / 原始文本),右边是搜索框、字号调节、主题设置、复制和导出的入口。不同版本排布略有差异,但功能集合基本一致。这个区域用得最多的是搜索框和视图切换。

中间主体区:树形视图下,每个节点前面有个小三角,点一下折叠或展开。键名和值用不同颜色区分,字符串、数字、布尔、null 各有各的色,扫一眼就能分辨类型。数组会显示元素个数,对象会显示属性个数,这个设计很贴心——不用展开就知道这个数组是不是空的。

路径显示区:通常在节点旁边或者页面底部,鼠标点到哪个节点,就显示它在这份 JSON 里的完整路径。这是整个插件里我用得最多的功能,没有之一。

4. 树形浏览的几个提效细节

4.1 折叠、展开与批量收起

树形视图的第一层价值是折叠。一份几百 KB 的响应,展开状态下一屏只能看十几个节点,可你通常只关心其中一两个分支。把所有顶层节点先收起来,再逐层展开你要看的那条路径,这个操作习惯建立起来之后,看大响应的效率会明显不一样。

折叠箭头的点击区域比想象中大一点,点键名本身有时也能触发折叠,具体看版本。数组和对象节点的箭头旁边会带元素数量,[12]表示这个数组有 12 项,{8}表示这个对象有 8 个属性。这个数字在排查"为什么前端遍历报错"这类问题时特别有用——一眼就能看出返回的是空数组还是压根没这个字段。

有个小细节值得注意:空对象和空数组的显示。{}和[]在树里是收不起来的状态,因为里面没东西。但null、空字符串""、数字0这几个在视觉上容易混淆。判断"字段有没有返回"和"字段返回了空值"是两件完全不同的事,前者是后端漏了,后者是后端有意为之。看树的时候别扫一眼颜色就下结论,鼠标点上去看路径栏里到底有没有这个 key。

4.2 路径复制:把坐标变成一句话

路径栏显示的格式一般是$.data.list[3].orderNo这种,$代表根节点,点号接属性名,中括号接数组下标。这个格式和 JSONPath 基本一致,粘到代码里当取值表达式用,或者直接发给同事,对方一看就知道该去哪一层找。

我现在的习惯是:定位到可疑字段之后,先复制路径,再复制值,两样一起发到群里。对方不用再问"在哪个位置",直接按路径去对应的地方核对。这个小动作省下的沟通成本,累计起来相当可观。

复制入口通常在节点上右键,或者在顶部工具条有一个复制按钮,点了之后把当前选中节点的路径复制到剪贴板。有的版本还支持复制整个子树序列化后的 JSON 片段,适合把某个分支单独拿出来做示例。

4.3 搜索过滤与类型着色

搜索框的行为要注意区分。有的实现是高亮匹配,把所有命中的位置标出来,树结构不变;有的是过滤,只显示包含匹配项的节点及其祖先链。第二种在处理超大响应时更好用,能直接把无关分支藏掉。

搜索的时候尽量带上引号或者用完整键名,比如搜"orderNo"而不是搜order,不然会命中一堆orderId、orderStatus、orderTime,反而更难找。如果只是想确认某个值存不存在,搜值本身也行,但要注意数字和字符串在搜索时的匹配规则可能不同。

类型着色这块,各版本配色不一样,但大体规律是字符串一个色、数字一个色、布尔一个色、null 单独一个色。用久了会形成肌肉记忆:扫一眼颜色分布,就能判断这个响应的字段类型是不是符合预期。比如本该是数字的金额字段显示成了字符串颜色,那多半是后端序列化时用了BigDecimal直接转字符串,或者是精度保护的处理,得进一步确认。

5. 编辑、格式化与导出

5.1 就地修改值

树形视图里双击某个值,通常可以进入编辑状态,改完回车生效。这个功能在两种场景下特别顺手。

一是构造测试数据。你拿到一份真实的响应,想验证前端在某个字段为空时的表现,不用去改后端,直接在树里把那个值改成null或者空字符串,然后导出成本地文件给前端同学。整个过程不碰服务端,不改数据库。

二是脱敏。要把一份响应贴进文档或者提给外部,里面有手机号、有内部标识,一个个手工替换太累。在树里改掉,再导出,比在文本编辑器里正则替换安全得多,至少不会漏。

但必须重复一遍前面说过的:这些修改只作用于当前页面展示,不会回写到任何地方。刷新页面,一切复原。指望它当接口调试工具的编辑面板,会失望。

5.2 格式化与压缩的双向切换

顶部通常有个美化 / 压缩的开关。美化就是标准的缩进格式,方便人看;压缩就是去掉所有空白字符的单行形式,方便复制到代码里当字符串常量,或者塞进某个配置文件。

这个切换看着不起眼,实际很实用。比如你要把一份响应作为 mock 数据写进前端代码,压缩形态直接复制过去,比美化形态省几十行。反过来,如果你的 JSON 是从某个日志里抠出来的、被压成了一行,粘进插件的原始文本视图,点一下美化,立刻就展开了。

5.3 导出到本地

导出功能把当前(可能已经被你编辑过的)内容存成.json文件。文件名默认一般是时间戳或者页面标题,建议改一下,不然下载目录里很快堆满一串看不出区别的文件。

导出这个动作在我的工作流里主要承担两个角色:一是把线上响应固化成测试夹具(fixture),放进项目的测试目录;二是作为 POST 请求的绕行方案的中转,这个下面单独讲。

6. POST 接口怎么才能用上它

6.1 这个限制的成因

这是使用这个插件绕不过去的一道坎。JSON-handle 的接管发生在顶层页面导航阶段,也就是浏览器地址栏发起的那次请求返回了 JSON。而 POST 请求没法从地址栏发——地址栏只能发 GET。你在开发者工具的 Network 面板里看到的那些 POST 响应,属于页面内部的异步请求,压根不经过顶层导航,插件没有介入的机会。

这不是设计缺陷,是浏览器扩展这套机制的天然边界。想清楚这一点,绕行方案就顺理成章了:想办法把 POST 的响应体,变成一个可以通过顶层导航打开的 JSON 地址。

6.2 方案一:复制响应,落地成文件(最稳)

最土但最可靠的办法。在开发者工具的 Network 面板里找到那个请求,切到 Response 标签,全选复制,粘到本地一个.json文件里,保存,然后把这个文件拖进浏览器窗口。

拖进去之后,浏览器是以file://协议打开的,内容类型按扩展名推断为 JSON,插件正常接管。整个链路不涉及任何网络请求,数据完全在本机,安全性最高。

缺点是需要手工建文件、粘贴、保存、拖拽,四步操作。如果只是偶尔看一次,这四步完全可以接受;如果要反复看同一个接口,就有点烦了。

提示:文件名别用中文和空格,某些环境下file://路径里的特殊字符会导致解析异常。用resp-20250101.json这种格式最保险。

6.3 方案二:在控制台里发请求,把结果转成可打开的地址

稍微进阶一点。打开目标站点的开发者工具,在 Console 里直接发一个 fetch,拿到响应文本之后,构造一个 Blob 地址并新开窗口。

fetch('/api/order/detail', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ orderId: 1001 }), credentials: 'include' }) .then(r => r.text()) .then(t => { const url = URL.createObjectURL(new Blob([t], { type: 'application/json' })); window.open(url, '_blank'); });

这段代码的关键在最后三行:把文本包成一个类型为application/json的 Blob,生成一个blob:开头的临时地址,然后新窗口打开。

但这里有个坑要提前打招呼:blob:地址不一定能被扩展接管。不同版本的浏览器和不同版本的插件,对 blob 地址的处理不一致,有时候打开的是格式化好的树,有时候还是一坨原始文本。我实测下来成功率大概一半一半,跟浏览器版本、插件版本都有关系。

所以这个方案的正确用法是:先试,不行就退回方案一。别在 Console 里反复折腾,试两次不生效就老实复制粘贴。真正稳定的永远是本地文件。

另外,控制台里发请求要注意跨域。如果当前页面和你请求的接口不同源,会被同源策略拦掉。最省事的做法是先导航到接口所在的域名下任意一个页面,再在控制台里发相对路径的请求,这样就是同源了。

6.4 方案三:让后端临时支持 GET

如果你的后端是自己能改的,最优雅的方案其实是让这个接口同时支持 GET,或者临时加一个调试用的 GET 路由。地址栏一敲,插件自动接管,什么问题都没有。

这不是"为了工具改架构",而是在调试阶段给自己留一条快车道。很多团队在开发环境里都会保留一两个只读的调试入口,上线前关掉或者加权限校验。前提是要有明确的开关和权限控制,别把调试入口带进生产。

7. 大数精度:一个必须提前知道的坑

7.1 十九位 ID 为什么显示错了

这个问题跟插件本身没太大关系,是 JavaScript 这门语言的数值表示决定的,但只要你在浏览器里看 JSON,就一定躲不开。

JavaScript 里的数字统一用双精度浮点数表示,能精确表示的整数上限是 2 的 53 次方减一,也就是 9007199254740991,十六位十进制数。超过这个范围,整数就没法精确表示了,末尾几位会被"抹平"成最接近的可表示值。

现代系统里常用的分布式 ID 生成方案,出来的 ID 动辄十八九位,比如1234567890123456789。这个数在原始文本里是准确的,问题出在解析环节:任何把它当成数字解析的地方,都会得到1234567890123456800这样的结果,末尾几位直接被改写。

现象很好认:页面上显示的 ID 和接口文档里的示例对不上,或者同一份数据刷新两次,显示的值末尾数字在跳。看到这种"末位漂移",基本可以断定是精度问题。

7.2 三种处理路径

第一种,看原始文本。插件顶部一般有树形 / 原始文本的切换开关,切回原始文本,看到的永远是服务端返回的原始字节,没有经过任何数值转换,十九位一位不差。这个方法零成本,代价是不能折叠不能搜索,只适合确认单个值。

第二种,让后端把大数序列化成字符串。这是行业里的标准做法。ID、订单号、流水号这类"标识符"本身不参与算术运算,用字符串传输完全合理,还能顺带避开所有语言和框架的精度差异。改法通常是在序列化配置里把长整型字段统一转成字符串,或者给对应字段加个注解。改完之后前端拿到的就是"1234567890123456789"带引号的形式,浏览器再怎么解析也不会丢精度。

第三种,用插件提供的原样保留选项。部分版本在设置里提供了针对大数的处理开关,开启后数字节点会以原始文本形式展示,不做浮点转换。这个我不太确定各版本的具体命名和位置,用之前先在设置页翻一遍,找到跟数字、精度、原样显示相关的选项。找不到就直接用前两种办法,别在这上面耗时间。

注意:不要试图在树形视图里手动把显示错的值改回去。你改的是一个已经被精度损坏的数字,改完导出,导出的还是错的。要看准确值,只能走原始文本或者让后端改。

8. 常见问题速查与排查思路

8.1 装了没反应

按这个顺序排查,基本能覆盖九成情况。

现象可能原因处理方式
页面还是原始文本内容类型不是 JSON看 Network 面板的响应头
页面完全空白响应体为空或只有空白字符确认接口是否真的返回了内容
只在部分地址生效该页面用了内容安全策略看控制台是否有拦截报错
无痕窗口里不生效扩展默认不在无痕模式启用在扩展详情里手动授权
昨天能用今天不能插件被更新或被禁用检查扩展列表里的开关状态

内容类型这一条要重点看。有时候服务端返回的确实是 JSON 字符串,但响应头写的是text/html,浏览器就按 HTML 渲染,插件不接管。改响应头是最彻底的解法。

无痕模式这条坑过不少人。Chrome 默认不允许扩展在无痕窗口运行,需要在扩展详情页里单独打开"在无痕模式下启用"的开关。调试一些需要隔离登录态的场景时会用到无痕窗口,忘了这个开关就会以为插件失效了。

8.2 和别的格式化插件打架

浏览器里同时装了好几个 JSON 相关扩展,是很常见的情况。可能是你以前装过别的格式化工具忘了卸,也可能是团队统一下发的工具包里带的。

两个扩展都想接管同一个页面的时候,谁生效取决于加载顺序和注册方式,表现就是"时好时坏"——有时候显示成 A 的界面,有时候显示成 B 的界面,有时候两个的样式叠在一起,页面乱成一团。

排查方法很直接:把其它 JSON 相关的扩展全部禁用,只留一个,刷新页面看是否稳定。稳定了就说明是冲突,之后按需取舍,别贪多。我个人的原则是同类工具只留一个,功能重叠的扩展每多一个,出问题的概率就多一分。

8.3 超大响应把页面拖死

几百 KB 的响应,树形渲染毫无压力。几 MB 的响应,展开全部节点就会明显卡顿,滚动掉帧,搜索要等好几秒。十几 MB 的响应,标签页内存直接飙上去,运气不好整个页面崩掉。

处理策略分三档:

  • 1 MB 以内:正常用,随便展开。
  • 1 MB 到 10 MB:先折叠全部,只展开目标分支;搜索时用完整键名,别用短词;实在卡就切到原始文本视图,用 Ctrl+F 定位,找到之后再切回来看看周边结构。
  • 10 MB 以上:别在浏览器里硬扛。存成文件,用编辑器打开,或者写个脚本只抽取需要的那几个字段打印出来。浏览器不是用来处理超大文本的工具,跟它较劲没有意义。

9. 和开发者工具的分工,以及一点个人习惯

9.1 两个工具各管一段

用久了会发现,JSON-handle 和开发者工具其实是互补的,管的是流程里的不同段落。

开发者工具管"过程":请求发了没有、状态码是多少、响应头对不对、耗时多长、有没有重定向、cookie 带没带上。这些都是"这次请求发生了什么"的问题。

JSON-handle 管"结果":响应体长什么样、字段层级怎么组织、某个值到底是什么类型、要取的那个字段在哪。这些是"这份数据是什么"的问题。

我的习惯是先看 Network 面板确认请求没问题,再复制响应到本地文件用插件打开看结构。如果只是快速确认某个字段,有时候连文件都不落地,直接把响应复制到插件的粘贴区(部分版本提供),看一眼就关。

9.2 几点实操建议

第一,把常用的 JSON 页面加书签。有些接口是 GET 的、返回结构固定,比如配置查询、字典查询、健康检查。加个书签,需要的时候一键打开,插件自动接管,比每次去翻文档找地址快得多。

第二,养成先折叠后展开的习惯。打开一个陌生响应,第一件事是把所有顶层节点收起来,然后按你关心的路径逐层展开。这个习惯能避免被无关分支干扰,也能减少大响应下的渲染压力。

第三,复制路径比复制值更有用。跟人沟通问题时,路径加上一句"这里返回的是空数组,预期应该有值",比截一整屏图有效得多。对方能直接定位,不用反问。

第四,注意别在公共场合开着敏感数据。插件展示的是完整的响应体,里面可能带手机号、带地址、带内部标识。演示或者录屏之前先确认一下,该脱敏的脱敏,该关的关。这不是插件的问题,是使用习惯的问题。

第五,定期清理下载目录里的导出文件。导出功能用起来太顺手,很容易攒下一堆response.json、response(1).json。里面可能有没脱敏的数据,堆在本地磁盘上不是好事。设个提醒,每周清一次。

9.3 它不适合干什么

最后说清楚边界,免得把它当万能工具用。

它不是接口文档工具。想生成接口文档、维护字段说明,得用专门的文档工具,插件只能帮你看单次响应。

它不是数据校验工具。想验证响应结构是否符合约定、字段类型是否正确,得靠自动化测试或者 schema 校验,人工看树只能覆盖很少一部分。

它也不是长期的调试工作台。如果你的日常是反复调十几个接口、维护环境变量、跑断言,那还是老老实实用接口调试客户端,插件只作为"快速看一眼"的补充。

我自己的用法一直很简单:需要快速定位一个字段、确认一个层级、复制一段路径的时候,地址栏一敲,看完就关。工具的价值在于顺手,不在于功能表有多长。装上一个季度用不了几次也没关系,真到需要的时候,它在那儿就行。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进