Protobuf 转 JSON
Protobuf 二进制在线解析为 JSON,有没有 .proto 都能解:支持十六进制、Base64、gRPC 帧,int64 和 Timestamp 按 ProtoJSON 输出不丢精度,也能把 JSON 编码回二进制。
- 在浏览器中处理
- 数据不离开你的设备
- 免费 · 无需注册
用微信扫描以下二维码即可分享
示例、说明与常见问题 带实际输出的示例、与同类工具的差别,以及常见问题。
示例:接口返回的雪花 ID
下面是一个用户服务的回包定义,id 是 64 位雪花 ID:
syntax = "proto3";
package api.user.v1;
message GetUserReply {
int64 id = 1;
string nickname = 2;
int32 level = 3;
bool vip = 4;
repeated string tags = 5;
Profile profile = 6;
}
message Profile {
string city = 1;
}
抓到的 18 字节是 08 fb 80 dc 97 de e9 dd b2 19 12 06 e5 b0 8f e7 8e 8b。按 api.user.v1.GetUserReply 解码:
{
"id": "1830000000000000123",
"nickname": "小王"
}
id 是字符串,这是 ProtoJSON 格式 对 64 位整数的规定。如果后端把它写成 JSON 数字,前端 JSON.parse 得到的是 1830000000000000000,末尾三位已经变了。
level、vip、tags 没有出现,因为它们是默认值。如果服务端用 Go 框架 Kratos v2,它的 JSON 编解码器(v2.8.4 的 encoding/json/json.go)调用 protojson 并设置了 EmitUnpopulated: true,接口会输出这些字段。勾选“输出默认值字段”可以对照:
{
"id": "1830000000000000123",
"nickname": "小王",
"level": 0,
"vip": false,
"tags": []
}
区别只有一处:protojson 的 EmitUnpopulated 会把未设置的消息字段写成 "profile": null,本工具的选项与 protojson 的 EmitDefaultValues、Python 的 always_print_fields_with_no_presence 一致,不输出它。
示例:手里没有 .proto
把 Schema 清空,原始视图选“JSON,附其他解读”,同样的字节变成:
{
"1": {
"uint64": "1830000000000000123",
"sint64": "-915000000000000062"
},
"2": "小王"
}
线路格式里 varint 不带类型,同一组字节按 int64 读是正数,按 sint64(zigzag 编码)读就是负数。字段 2 是合法 UTF-8 文本,直接显示为字符串。选“protoc —decode_raw”视图,输出与 protoc --decode_raw 逐字相同,中文会显示成八进制转义。
示例:JSON 编码回二进制,带多余字段
联调时前端多传了一个 avatar_url:
{"id": "1830000000000000123", "nickname": "小王", "avatar_url": "https://example.com/a.png"}
在“JSON → 二进制”中直接报错,并给出位置:
api.user.v1.GetUserReply(第 1 行第 49 列):api.user.v1.GetUserReply 没有字段“avatar_url”。
Kratos v2 的反序列化设置了 DiscardUnknown: true,服务端会静默丢掉这个字段。勾选“忽略未知字段”得到同样的结果,说明里会写明忽略了哪个字段:
08 fb 80 dc 97 de e9 dd b2 19 12 06 e5 b0 8f e7 8e 8b
编码结果与抓到的字节完全一致。字段名写 nickname、枚举写名称或数字、int64 写字符串或数字都可以;输出可选十六进制、Base64、Python 字节串、C 数组,也可加 gRPC 帧头或下载为 .bin。
与其他在线工具的区别
2026-10-02 用本页英文版的订单示例(含 Timestamp 与超过 2^53 的 int64)实测。365 工具箱(toolbox365.cn)和 codertools.net 都用 protobufjs 解析 .proto:带 import "google/protobuf/timestamp.proto" 时,365 工具箱报“no such Type or Enum ‘google.protobuf.Timestamp’”,codertools 的消息类型列表为空;去掉 Timestamp 字段后,两者都把 order_id 输出成 "9007199254740992"(比真实值小 1),字段名保持下划线写法。365 工具箱的无 Schema 模式数值准确,并列出多种解读,但粘贴带 gRPC 帧头的数据时报“偏移 1 处 field number 为 0”,需要手工去掉前 5 字节。以上工具都没有把数据发到服务器。
限制
- 只接受 .proto 源文件。
protoc --descriptor_set_out生成的描述符集合和文本格式消息都不能载入。内置的 import 只有any、duration、empty、field_mask、struct、timestamp、wrappers;google/api/annotations.proto等其他文件里如果有用到的类型,需要手动添加。扩展descriptor.proto的自定义选项会被忽略,选项不影响字节。 - 未知字段不进 JSON。说明里列出编号、线路类型和字节位置,并给出能无未知字段解码的消息类型。
- 类型选错也可能“成功”。二进制不带类型名,选错类型时常会解出奇怪的值,注意说明里的未知字段提示。
- 嵌套最多 100 层,打开的文件不超过 2 MB;压缩帧只支持 gzip。
- 支持 proto2 与 editions 2023/2024:组、required、封闭枚举、扩展(
"[pkg.ext]")、字段存在性、packed 与 expanded、delimited 消息。proto3 的string如果不是合法 UTF-8 会报错并给出字节位置,二进制数据应改用bytes。
相关工具:用 HAR 文件分析器 查看抓包,用 Base64 编码 / 解码 转换载荷,用 JSON Schema 验证器 检查 JSON。
FAQ
没有 .proto 文件能解析吗?
能。Schema 留空时按 protoc --decode_raw 的方式解码,输出字段编号、数字、字符串和嵌套消息。字段名、枚举名、有符号和 64 位类型以及 Timestamp 这类知名类型需要 .proto,因为二进制里没有这些信息。
为什么 int64 输出成字符串?
ProtoJSON 规定 int64、uint64、sint64、fixed64、sfixed64 写成十进制字符串。JavaScript 把 JSON 数字读成 double,超过 2^53 就会丢位,雪花 ID 1830000000000000123 会变成 1830000000000000000。本工具用 BigInt 解码 64 位字段,数字一位不丢。
输出里为什么少了某些字段?
ProtoJSON 不输出取默认值(0、空字符串、false、枚举第一个值)的 proto3 普通字段。勾选“输出默认值字段”即可显示。字段编号不在 Schema 里的未知字段无法写进 ProtoJSON,“说明”里会逐个列出编号和字节位置。
gRPC 抓包数据怎么解?
直接粘贴。gRPC 帧选“自动”时,工具会去掉每条消息前 5 字节的帧头,逐条解码;gRPC-Web 的 trailers 帧显示在说明里,压缩标志为 01 的帧会先用 gzip 解压。
数据会上传吗?
不会。解析、解码和编码都在浏览器里完成。页面只保存选项,不保存 Schema、字节或 JSON。