如何在JSON中发送二进制数据

Base64十六进制编码JSON传输二进制
On this page

如何在JSON中发送二进制数据

摘要

Base64 和十六进制编码可以通过将二进制转换为文本表示,实现在 JSON 中发送图像、文件等二进制数据。


JSON(JavaScript 对象表示法)由于其轻量级的文本表示而成为一种流行的数据格式。但 JSON 本身只支持文本字符串,不能处理像图片、音频、PDF 等原始二进制数据。在这篇文章中,我们将探讨一些在 JSON 中编码二进制数据以进行传输的技术。

什么是 JSON?

JSON 是一种用来表示结构化数据的文本格式,它的设计目标是便于人阅读和编写,同时也便于机器解析。它由以下两部分组成:

  • 字段名称和值作为字符串键值对
  • 数组中的有序值列表

例如:

1{
2  "name": "张三",
3  "age": 30,
4  "hobbies": ["编程", "远足", "摄影"]
5}

由于其相对于 XML 的简单性,JSON 常用于 web API、配置文件和数据存储。但 JSON 仅支持基于文本的数据类型,如字符串、数字、布尔值等。它没有原生处理二进制数据的方法。

在 JSON 中发送二进制数据的方法

在 JSON 中传输二进制数据主要有以下几种编码方式:

  • Base64 数据编码
  • 十六进制编码
  • 自定义二进制字段约定

我们来看一下每种方法的优缺点。

Base64 编码

Base64 是一种将二进制数据转换为文本格式的编码方式,使用了 64 个可打印的 ASCII 字符。它通常用于在基于文本的渠道上发送二进制数据。

Base64 在几乎所有语言和平台上都有很好的支持。将二进制数据编码使其易于嵌入 JSON 字符串中。

缺点是与原始二进制相比,base64 编码会使数据大小增加约 33%。

例如,一个 2KB 的图像编码后可能会变成 2.7KB。对于小文件来说,这种开销通常是可以接受的。

十六进制编码

另一种选择是将二进制数据编码为十六进制文本字符串。这会将每个二进制字节转换为两个十六进制字符。

与 base64 相比,十六进制编码的开销更小,通常只有约 10-15%的增加。但是,十六进制编码并不像 base64 那样拥有广泛的库支持。

自定义二进制字段

与直接编码二进制数据不同,另一种方法是定义描述外部存储二进制数据的自定义 JSON 字段。

例如:

1{
2  "filename": "image.png",
3  "size": 25536,
4  "url": "https://example.com/images/image.png"
5}

这避免了任何编码开销,但需要客户端处理外部的二进制存储和检索。

编码与外部存储的选择

对于几 KB 以下的小二进制有效负载,直接以 base64 或十六进制编码到 JSON 中是可行的。但是对于较大的文件,如多媒体,最好是外部存储,而在 JSON 中引用。

编码的优点:

  • 简单 - 不需要外部存储
  • 自包含的有效负载

外部存储的优点:

  • 没有编码导致的体积增大
  • 可以利用优化的二进制存储

客户端和服务器处理

在客户端,二进制数据可以在放入 JSON 之前编码为 base64 或十六进制。

在服务器端,在解码之前应对编码的数据进行验证和清理,以防漏洞。

对于外部自定义字段,服务器必须使用元数据检索二进制文件。处理远程文件引用时需要考虑一些安全问题。

示例

一些可以在 JSON 中传输二进制数据的例子:

  • 文件上传 API - 将图像二进制以 base64 编码
  • 应用配置 - 嵌入证书和资源的 base64 编码
  • 聊天应用 - 发送音频片段和图像的十六进制或 base64 编码

总结

虽然 JSON 本身只支持文本,但可以通过多种方式在 JSON 中编码或引用二进制数据。对于几 KB 以下的小二进制数据,直接使用 base64 编码提供了一个简单的解决方案。对于大文件或需要优化存储,使用指向外部二进制的自定义 JSON 字段会更好。与任何编码一样,需要根据特定的使用案例平衡方便性和效率。