JSON ↔ YAML 转换完全指南:有损无损、类型坑与配置迁移
把接口返回的 JSON 改成 Helm values、把 docker-compose 片段喂给只认 JSON 的脚本,或在 K8s 清单与 API 载荷之间来回拷时,最容易翻车的不是「语法长什么样」,而是类型与注释在互转中悄悄丢失。本指南聚焦 JSON↔YAML 的有损/无损边界、类型坑与可操作步骤,直接对接 WebUtils 本地转换页。
核心一句话
JSON 子集进 YAML 多半可逆;带注释、多文档、锚点的 YAML 再转回 JSON 一定有损。
先想清楚目标是「给人读的配置」还是「给程序解析的数据」,再决定方向与是否允许丢信息。转换前最好各自格式化/校验一遍,转换后再用目标语言的解析器核对关键字段类型。可在 JSON ↔ YAML 转换 上对照练习。
1. 两种格式各自擅长什么
JSON 与 YAML 都能表达对象、数组、字符串、数字、布尔和空值,但工程角色不同。
| 维度 | JSON | YAML | 互转时的含义 |
|---|---|---|---|
| 语法载体 | 括号、引号、逗号 | 缩进 + 少量符号 | YAML 更易手写,JSON 更易机器吐出 |
| 注释 | 标准不支持 | # 行注释 |
YAML→JSON 注释必丢 |
| 多文档 | 单根值 | --- 可多文档 |
JSON 一侧通常只能保留一个根 |
| 键类型 | 键必须是字符串 | 键可为多种标量(实现相关) | 非字符串键转 JSON 会字符串化 |
| 引用/锚点 | 无 | & / * |
展开或丢失,视实现而定 |
| 尾逗号 | 非法 | 不适用 | 从「类 JSON」粘贴常先卡在 JSON 侧 |
何时优先 JSON: API 响应、前端状态、多数语言的标准库开箱即用、需要严格可互操作的契约。
何时优先 YAML: K8s、Compose、CI、Ansible、Helm values——人要改、还要写注释和多段文档。
两者不是「同一种东西的两种皮肤」。互转是投影:能保留的是共享数据模型;格式专属能力会在边界被削掉。
2. 有损与无损:一张对照表
下面按「往返一次是否还能得到等价结构」判断。等价指解析后的数据模型一致,不要求空白、键序、引号风格完全相同。
| 输入特征 | JSON → YAML | YAML → JSON | 往返建议 |
|---|---|---|---|
| 纯对象/数组 + 标准类型 | 通常无损 | 通常无损 | 可放心互转 |
含 # 注释 |
不适用(JSON 无注释) | 有损(注释消失) | 注释只留在 YAML 源 |
多文档 --- |
不适用 | 有损(常只取首段或失败) | 先拆文档再转 |
锚点 &anchor / 别名 *anchor |
不适用 | 可能展开或报错 | 展开后人工核对 |
未加引号的 01、yes、on |
JSON 侧无此写法 | 可能变成数字/布尔 | 关键标量加引号 |
键为 true / 1 等 |
JSON 键皆字符串 | 实现可能特殊处理 | 转 JSON 后检查键名 |
| 超大整数 / 科学计数 | 受 JS Number 影响 | 同样受解析器影响 | 金额、雪花 ID 用字符串 |
二进制/自定义标签 !! |
不适用 | 多数在线工具不支持 | 勿依赖浏览器工具还原 |
实践原则:
- 配置源以 YAML 为权威时,JSON 只是导出物;不要把导出 JSON 再写回覆盖带注释的 YAML。
- 接口契约以 JSON 为权威时,YAML 只是给人看的草稿;提交前应用 JSON Schema 或示例响应校验。
- 任何「看起来像数字/布尔」的业务码,在 YAML 里加引号,再转 JSON,避免静默变类型。
前后对照示例
合法 JSON:
{
"replicas": 3,
"image": "nginx:1.25",
"debug": false,
"note": "生产勿开"
}
转成常见 YAML 形态(风格因实现略有差异):
replicas: 3 image: nginx:1.25 debug: false note: 生产勿开
若 YAML 写成未加引号的版本号与开关,再转回 JSON 可能变成:
{
"port": 80,
"enabled": true,
"version": 1.10
}
而你本意可能是字符串 "1.10"(保留尾零)或字符串 "80"。类型一旦在中间态被猜错,业务校验会在很远的地方才爆。
故意有损的 YAML(含注释与多文档)无法完整变成单个 JSON 值:
# 仅文档 A --- name: api --- name: worker
在线转换器通常只能给你其中一个映射,或直接报错。正确做法是按文档切开,分别转换。
3. 类型坑:YAML「帮你猜」时最伤
JSON 类型集合小而硬:string / number / boolean / null / object / array。YAML 1.1 风格的解析器常把未加引号的标量猜成布尔、整数、浮点、时间戳。WebUtils 转换页基于浏览器内的 js-yaml 一类实现,行为接近常见前端工具链,但不等于你服务器上的 PyYAML 或 Go yaml.v3 逐字节一致。
| YAML 写法 | 常被解析成 | 转 JSON 后 | 稳妥写法 |
|---|---|---|---|
yes / no / on / off |
布尔(YAML 1.1) | true/false |
"yes" |
010 |
八进制或整数 | 数字 8 或 10 |
"010" |
1.0 |
浮点 | 1 或 1.0 |
需要字符串时加引号 |
2026-08-08 |
日期/字符串(实现相关) | 字符串或特殊对象 | 明确加引号 |
空节点 key: |
null |
null |
需要空串写 "" |
~ 或 null |
空 | null |
与空字符串区分清楚 |
国家代码、工号、订单号、权限码、镜像 tag 中的数字——一律当字符串处理,直到你证明业务层要的是数值运算。
JSON 侧也有坑:标准 JSON 没有 undefined,没有 NaN/Infinity,键必须双引号。从 JS 对象 JSON.stringify 时 undefined 字段会被丢弃;若你先在控制台抄「长得像 JSON」的对象字面量(单引号、尾逗号),转换器会先在 JSON 解析阶段失败——这时应先走 JSON 格式化 修到合法,再转换。
4. 在 WebUtils 上怎么转
主工具页:JSON 转 YAML / YAML 转 JSON(站点另有开发分类下的 dev 版,能力同属互转;本指南步骤以 converter 双栏为准)。
JSON → YAML
- 打开转换页,左侧(或 JSON 区域)粘贴文本。
- 若来源是压缩一行或可疑片段,先在 JSON 格式化 校验并美化,确认无语法错误。
- 点击 「JSON ➔ YAML」。
- 在 YAML 区域检查:层级是否与原对象一致、布尔与数字是否仍是你期望的类型、字符串是否被无意义地拆行。
- 需要复制时用区域旁的 复制;贴进仓库前在本地再用项目同款解析器(如
kubectl、yamllint、CI 里的 schema)扫一遍。
YAML → JSON
- 将 YAML 粘贴到 YAML 区域。多文档时先手工只保留当前要转的一段。
- 缩进混乱或 Tab 混用时,先用 YAML 格式化 统一空格并校验。
- 点击 「YAML ➔ JSON」。
- 打开结果,重点盯:曾未加引号的字段类型、原注释是否已消失(预期行为)、根是否仍是对象/数组。
- 若下游是 API,用格式化工具再缩进一次,便于 Code Review;入库或传输再考虑压缩。
失败时看什么
- JSON 解析失败: 缺逗号、单引号、尾逗号、多余
undefined——回格式化工具定位行列。 - YAML 解析失败: 缩进不对齐、
:后空格缺失、Tab——回 YAML 格式化或对照错误表。 - 能转但「值不对」: 几乎总是类型猜测或注释/多文档被丢掉——回到上一节对照表,而不是反复点转换按钮。
处理含账号、Token、内网地址的配置时,先脱敏再粘贴。WebUtils 工具在浏览器本地处理,不替代你的保密规范;公共电脑上用完应清空文本框。
5. 常见错误与处理
| 现象 | 可能原因 | 怎么处理 |
|---|---|---|
| JSON 侧报 Unexpected token | 单引号、尾逗号、注释 // |
先格式化修成标准 JSON |
| YAML 报 bad indentation | 空格数不一致或 Tab | 全文件统一 2 空格,禁 Tab |
转换后 enabled 变成 true 而业务要字符串 |
未加引号的 yes/on |
源 YAML 加引号后重转 |
版本号 1.10 变成 1.1 |
浮点规范化 | 写成 "1.10" |
| 只转出多文档中的一段 | 工具按单文档模型工作 | 按 --- 拆分 |
| 注释全部消失 | YAML→JSON 固有限制 | 注释保留在 YAML 源文件 |
| 超大 ID 末几位变化 | IEEE 双精度整数精度 | ID 全程字符串 |
| K8s apply 说字段类型错 | 清单里数字/字符串与 CRD 不符 | 对照 CRD,互转后检查类型 |
| 中文或特殊标量被拆成多行 | 折行/样式选择 | 关键标量用引号或显式 block |
6. 真实工作场景
场景 A:接口 JSON 改成 Helm values 草稿
后端给了应用配置的 JSON 样例,要写进 values.yaml。步骤:JSON 格式化确认结构 → 转到 YAML → 人工加注释(环境差异、密钥来源)→ 把密钥改成 valueFrom 或占位符,不要把生产密钥留在 values 里再提交。往返时以 Git 中的 YAML 为准,JSON 样例只作初始骨架。
场景 B:同事只发 YAML 片段,前端 Mock 要 JSON
从 Compose 或 Action 里抠出一段 environment 映射,需要变成前端 mock 或 Postman body。先确认片段是单一映射而非多文档;YAML→JSON 后检查所有环境变量值是否仍为字符串(PORT: 8080 常被收成数字,而 process.env 体系里往往是字符串)。
场景 C:K8s 与运维脚本双轨
GitOps 仓库用 YAML,某审计脚本只吃 JSON。流水线里应用同款库做转换并跑 schema,而不是每次人工点在线工具。在线工具适合改一两个字段时的即时预览;批量与门禁仍应自动化。转换后用 JSON Diff 对比「上一版导出」与「本版导出」,避免缩进美化造成的假差异干扰——对比前两边都格式化。
场景 D:OpenAPI 同时提供 JSON 与 YAML
规范允许两种表达。编辑时选一种为源(许多团队用 YAML 方便 diff 注释),发布时生成另一种。生成物中的 $ref、discriminator 等结构应保持引用语义;若在线工具把复杂文档扁成丢失引用的树,说明该文件超出「简单配置互转」范围,应改用官方/专用转换链。
7. 发布前检查清单
- [ ] 已明确权威格式(JSON 契约 vs YAML 配置源)
- [ ] 转换前源文本已通过对应格式化/校验工具
- [ ] 多文档、锚点、自定义标签已排除或专项处理
- [ ] 业务码、ID、版本号等已按字符串保护(加引号)
- [ ] YAML→JSON 后接受「注释消失」并已把注释留在源文件
- [ ] 关键字段类型与下游 schema / CRD / 接口文档一致
- [ ] 脱敏后再粘贴到在线工具;用完清空
- [ ] 需要提交仓库的文件已用项目本地工具重跑一遍,不单靠一次网页结果
9. 常见问题
互转一定是无损的吗?
不是。双方共享的核心数据模型在实现正确时可近似无损,但注释、多文档、锚点、YAML 特有类型标签与样式(flow/block)无法在标准 JSON 里原样保留。把「能 parse」当成「完全可逆」会在配置管理里埋雷。
为什么我的 `yes` 变成了 `true`?
这是 YAML 1.1 风格布尔的典型表现:未加引号的 yes/no/on/off 常被收成布尔。业务若需要字面量,在源 YAML 写成 "yes" 再转换。不要在 JSON 结果里手工改回字符串却忘记改源,下次还会错。
转换器和格式化工具有什么区别?
格式化(JSON 或 YAML)解决「能不能读、合不合法、缩进齐不齐」;转换解决「同一份数据用另一种语法表达」。先合法再转换。非法 JSON 点「转 YAML」只会得到解析错误,不会「智能修好再转」。
大文件或含密钥的配置能贴吗?
浏览器本地处理降低了「上传到未知服务器」的风险,但屏幕分享、浏览器扩展与公共设备仍可能泄露。生产密钥、证书、连接串应脱敏或只在内网可信环境处理;超大文件可能让页面卡顿,优先用本地 CLI。
K8s 清单转成 JSON 后 apply 失败是怎么回事?
常见原因:字段类型与 CRD 不符、多文档被吞、或 integer/string 在互转中被改写。先 kubectl 客户端侧验证,再对比转换前后关键路径的类型,而不是只看 YAML「好不好看」。
10. 下一步
- 打开 JSON ↔ YAML 转换,用本文「replicas / image / debug」示例走通 JSON→YAML。
- 故意写一段带
yes与1.10的 YAML,转 JSON 观察类型,再改成加引号的版本对比。 - 把真实工作中的一份非敏感配置走「格式化 → 转换 →(可选)Diff」闭环,把检查清单固化进团队习惯。
- 若日常主要是改 YAML 缩进,收藏 YAML 格式化;主要是追 API 字段,收藏 JSON 格式化。