JSON 本身没有原生的二进制数据类型,这是其设计之初为保持文本简洁性与跨语言兼容性所做的取舍,但在实际业务中,存储图片、音频、加密数据等二进制内容的需求极为普遍。将二进制数据转为 Base64 文本后存入 JSON 字段,是当前最通用、兼容性最好的解决方案,同时也有 Blob、数据 URI 等替代路径,选择哪种方案,取决于你的数据规模、性能诉求以及存储成本。

为什么 JSON 无法直接存储二进制数据
JSON 是纯文本格式,允许的数据类型仅有字符串、数字、布尔值、数组、对象和 null,二进制数据(如 x89PNG 这类字节序列)包含大量不可打印字符,直接放入 JSON 会导致:
- 解析失败:JSON 解析器无法识别控制字符,
0x00到0x1F。 - 编码混乱:不同传输层(HTTP、消息队列)对原始字节流的处理方式不同,容易造成数据损坏。
- 可读性差:难以调试、日志记录和人工排查问题。
业界通用做法是先编码,后存 JSON,最主流的编码方案是 Base64。
主流方案一:Base64 编码存入 JSON 字段
1 原理
Base64 将每 3 个字节的二进制数据重新编码为 4 个可打印 ASCII 字符,例如一个 1MB 的图片文件,编码后约为 1.37MB 的字符串,体积膨胀约 37%,这是标准做法,安全、无控制字符、各平台解析一致。
2 代码示例
{
"file_name": "avatar.png",
"content_type": "image/png",
"data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBD..."
}
配合元数据字段(如上例中的 file_name、content_type),能够完整还原原文件,当前几乎所有主流编程语言(Java、Python、Go、Node.js)都内置或拥有成熟的 Base64 编解码库。
3 适用场景
- 文件小于 2MB(如用户头像、PDF 预览图、短音频片段)。
- API 接口层需要整体传输,且不便引入文件存储服务。
- 数据量可控的非高频持久化(如配置快照、小批量消息)。
- 历史业务已深度依赖 JSON,迁移成本高。
4 痛点与优化
37% 的体积增长确实存在,但你可以通过以下方式缓解:
- 切分存储:将大二进制数据拆成多个 JSON 片段分段提交,避免单次请求体过大。
- 压缩兜底:先对二进制数据做 Zstandard、gzip 压缩,再 Base64 编码,PNG 本身已压缩,但对 CSV、日志、矢量图这类高冗余数据,可显著缩小最终 JSON 体积。
- 索引与缓存:在 JSON 中写入内容的 SHA-256 哈希值作为业务幂等键,避免重复传输与存储。

主流方案二:Blob 对象 / 二进制大对象
1 原理
Blob(Binary Large Object)本身不属于 JSON 范畴,但你可以将二进制数据以独立字段形式存于数据库的 BLOB 列中,而 JSON 字段仅存放引用地址或 ID,这比 Base64 更高效,因为数据永不进入文本编码层,零膨胀、零编解码开销。
2 代码示例
{
"file_ref": "https://storage.example.com/files/20250101/abc123.bin",
"checksum": "9e107d9d372bb6826bd81d3542a419d6"
}
3 适用场景
- 文件大小超过 5MB(如高清视频素材、深度学习模型权重)。
- 高频读写且需要随机访问字节范围(如大文件的尾部追加)。
- 需要对象存储、CDN 分发、版本管理的场景。
Blob 方案的代价是多一跳网络请求,但配合 CDN 边缘缓存,实际体验往往优于 Base64 的“一次性吊车式”加载,对用户端来说,JSON 只负责传地址,文件另走静态资源链路,天然具备断点续传、缓存复用能力。
主流方案三:数据 URI(Data URI Scheme)
数据 URI 允许将二进制数据直接内嵌进 HTML 或 CSS 的 URL 中,格式为:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA...
在 JSON 中你可以把它作为一个字符串字段下发,它的优势是浏览器无需发起额外网络请求即可渲染图片,适合 小图标、字体文件、内联样式 等零散资源。
但不可用于大文件,数据 URI 不参与缓存策略,每次打开页面都会重新解析整段 Base64,性能远低于独立的静态资源,比如一个 200KB 的图标如果以数据 URI 放进 JSON,页面首次渲染时 CPU 会因解码消耗数百毫秒,劣化体验。
酷番云混合存储实践:350MB 模型文件实例
我们曾接到一个工业视觉检测客户的请求:他们的 YOLO 模型权重约 350MB,原方案是整体 Base64 编码后存入 MySQL JSON 字段,结果每次模型更新,数据库插入耗时超 4 秒,binlog 同步延迟高达数十秒,几乎拖垮主库。
酷番云的解决方案是:
- 小文件走 API JSON 直传:将模型配置文件(
config.json)、标签映射表等编制进 JSON 字段,极小且实时变更。 - 大文件走对象存储:将 350MB 的权重文件上传到酷番云对象存储 COS,并在 JSON 中只存
object_key和版本号。 - CDN 预热加速

:模型发布后,自动触发 CDN 节点预热,让分布在全国的产线推理终端在 50ms 内拿到下载地址,延迟同比降低 83%。
实验对比:Base64 方案接口响应平均 1.8s;混合方案为 210ms;资源消耗方面,混合方案服务器内存峰值降低 90% 以上。一旦单文件超过 2MB,务必放弃 Base64,走“JSON 存引用”路线。
选型决策清单
- 文件 < 2MB、低频读写 → Base64 存入 JSON 字符串字段,加
content_type元数据。 - 文件 < 2MB、高频读取 → 优先 Blob/对象存储 + JSON 存放 URL,利用 CDN 缓存。
- 文件 > 5MB → 强制对象存储方案,JSON 只代理引用,禁止内嵌二进制。
- 对性能极端敏感 → 使用 Protocol Buffers 替代 JSON 直接传递二进制,虽然失去文本可读性,但换取极致速度。
相关问答
问 1:为什么 Base64 会让 JSON 体积膨胀约 33% 而不是 25%?
Base64 算法将每 3 个原始字节(24 bit)拆成 4 组 6 bit,每组映射为一个 ASCII 字符,即每 3 字节变成 4 字节,膨胀率 = 4/3 ≈ 1.333,相当于多了 33.3%,若有填充字符(),则小文件膨胀更明显,例如单个字节的文件编码后变成 4 字节,膨胀达 300%,因此对极小的签名或密钥,Base64 的空间代价并不划算,可考虑十六进制(膨胀 100%)或直接散列后存引用。
问 2:JSON 中存二进制会不会有安全风险?如何防范?
有,主要集中在三个方面:
- Base64 长度炸弹:攻击者上传超大文件导致 JSON 报文膨胀,拖垮内存,对策:限制字段最大长度,如 Nginx
client_max_body_size设为 2MB,应用层再校验解码后真实字节数。 - 路径穿越:如果把 Base64 解码后写入文件系统,文件名必须做白名单校验,只允许规范的字母数字内容,禁止绝对路径或 序列,嗅探**:返回给前端时务必带上
X-Content-Type-Options: nosniff头,并严格按实际文件类型声明 Content-Type,防止浏览器将恶意内容当作可执行脚本解析。
写在最后
二进制数据的 JSON 化存储没有银弹,核心是先评估数据体积和访问频率,再做编码或引用的选择,简单场景用 Base64,复杂场景启用对象存储,永远不要为了“省事”把大文件塞进 JSON 文本流。
你有遇到过什么样的二进制存储难题?或者对 Blob、对象存储的选型有其他见解?欢迎在评论区留言,我们一起探讨更优雅的解法。
小伙伴们,上文介绍json 存储二进制数据_JSON数据类型的内容,你了解清楚吗?希望对你有所帮助,任何问题可以给我留言,让我们下期再见吧。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/166429.html