用原生 JavaScript 做一个本地 JSON 体检台:从格式化到结构对比
接口调试中经常要做三件小事:把一行响应展开、比较两份配置、把整理结果保存。单独看都很简单,但把真实接口数据复制到不同网站,容易忘记数据去了哪 里。今天做了一个小工具,将这些步骤放在浏览器内完成,作为一次原生 JavaScript 的实践。代码由 AI 辅助生成和整理,本文记录实际实现和验证结果,不包含生产账号或接口数据。
1. 先确定数据处理边界
工具使用 HTML、CSS 和 ES 模块,没有前端框架和第三方运行时依赖。页面由本机 Node 服务提供,监听 127.0.0.1:31849;输入只进入浏览器内存,不发往服务端,也不写入 localStorage。这样的设计适合临时调试,但刷新页面会丢失输入,因此提供了主动下载功能。
服务只允许读取 index.html、style.css、app.mjs 和 core.mjs 等明确列出的资源。仓库中的说明、测试文件和其他目录不会被自动暴露。响应设置正确的 JavaScript MIME 类型,并通过 CSP 将 connect-src 设为 none,减少后续误加网络请求的机会。
运行方式是安装 Node.js 18 或更新版本后,在仓库根目录执行:
node serve.mjs
然后打开 http://127.0.0.1:31849。页面使用 ES 模块,应通过 HTTP 加载,不能把双击 HTML 文件当成可靠的运行方式。本次验证在本机完成,没有为此创建 ECS 或其他付费云资源。
2. 校验与格式化共用一个入口
解析前先用 TextEncoder 计算 UTF-8 字节数,单份输入限制在 512 KiB。文本框与文件导入都走这个检查,避免只限制文件大小,却允许粘贴远超限制的内容。对 UTF-8 BOM 先做去除,再交给 JSON.parse 解析。
格式化使用 JSON.stringify(value, null, 2),压缩则省略缩进参数。解析失败会显示带左右侧标识的浏览器错误消息,不会覆盖原始文本。每份数据同时统计节点数、最大嵌套深度和不安全整数数量,便于快速观察复杂度。
3. 对比对象时忽略键顺序,对比数组时保留顺序
直接比较两段字符串,会把缩进和对象键顺序变化也算成差异。因此这里先解析,再递归比较数据结构。
const a = { region: 'cn-north-4', count: 2 };
const b = { count: 2, region: 'cn-north-4' };
// 两个对象的键顺序不同,但结构和值一致。
基本值使用 Object.is 比较;遇到对象,遍历两侧自有键的并集,标记仅左侧存在、仅右侧存在以及值或类型变化。数组仍按索引比较,所以 [1, 2] 和 [2, 1] 会产生两处差异。
结果路径使用 JSON Pointer 的转义规则:字段名中的斜杠变为 ~1,波浪号变为 ~0。例如字段 a/b~ 的路径为 /a~1b~0。最多显示 200 处差异,并在界面明确提示上限,避免把截断列表当成完整差异集合。
4. 展示结果时不要执行输入
JSON 值可能包含 HTML 字符串。差异列表使用 createElement 和 textContent 构建,不把输入拼接到 innerHTML。导出通过 Blob 与临时对象 URL 实现,下载后回收 URL。文件读取使用 File.text,在浏览器本地解析,不需要上传接口。
这些做法不能替代完整的安全评估,但能在小工具中建立清晰边界:数据作为数据处理,展示作为文本输出,不使用 eval,也不执行用户输入。
5. 明确 JSON.parse 的限制
有两个限制容易被忽略。第一,重复对象键会保留最后一个值,当前版本不检测重复键。第二,JavaScript Number 无法精确保存所有大整数,例如超过 2 的 53 次方减 1 的数字 ID。工具会提醒不安全整数,但提醒发生时解析已经完成,不能恢复被舍入的原始数值。因此长 ID 应写为字符串;需要数值字面量精确保留的业务,应选用支持大整数的专门解析器。
当前版本也不支持 JSON5 注释、尾随逗号、JSON Schema 或大文件流式处理。极深的嵌套仍可能达到浏览器调用栈上限。限制应写在页面上,帮助使用者判断是否适用。
6. 用实际行为验证工具
核心断言覆盖 BOM、无效语法、大小限制、键顺序、数组顺序、特殊路径、特殊键、不安全整数和差异数量上限。浏览器验证则检查示例变化、错误提示、文件导入、下载、清空、纯文本展示和手机宽度下的布局。此次执行没有页面脚本错误,也没有向外部域名发送请求;验证结果保存在仓库的 verification.json。
项目源码:https://gitcode.com/gcw_BaPcxR4k/local-json-workbench 。这是一个适合学习数据边界、模块拆分与浏览器文件 API 的小项目,后续若加入 Schema 或精确数值解析,应继续保持输入大小、性能和依赖成本可见。
- 点赞
- 收藏
- 关注作者
评论(0)