如何解码tonic-web返回的响应数据?
解码tonic-web响应数据的解决方法
核心步骤
1. 去除gRPC-Web响应前缀(关键)
tonic-web默认返回的gRPC-Web响应会带有5字节前缀:
- 第1字节:压缩标识(0=未压缩,1=gzip压缩)
- 后4字节:大端序的消息长度
直接解码完整的Base64转换数组会失败,必须先截取掉前5字节,取剩余部分进行解码。
2. Base64转Uint8Array
把前端获取到的Base64响应字符串转换成Uint8Array:
function base64ToUint8Array(base64: string): Uint8Array { const binaryString = atob(base64); const len = binaryString.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { bytes[i] = binaryString.charCodeAt(i); } return bytes; }
3. 用@protobuf-ts生成的消息类解码
假设你定义的proto消息如下:
// 对应"335"的响应消息 message NumberResponse { int32 value = 1; } // 对应"Hello stackoverflow!"的响应消息 message StringResponse { string message = 1; }
通过@protobuf-ts/plugin生成TypeScript类后,执行解码:
import { NumberResponse, StringResponse } from './generated/proto'; // 处理带前缀的响应 const base64Resp = "你的Base64响应字符串"; const fullBytes = base64ToUint8Array(base64Resp); // 去掉前5字节前缀 const payloadBytes = fullBytes.slice(5); // 解码数字响应 const numberResp = NumberResponse.decode(payloadBytes); console.log(numberResp.value); // 输出335 // 解码字符串响应 const stringResp = StringResponse.decode(payloadBytes); console.log(stringResp.message); // 输出Hello stackoverflow!
排查验证
- 如果解码失败,先打印
payloadBytes的十六进制值,对比proto手动编码结果,确认消息字段ID和类型是否匹配 - 确认后端tonic-web是否配置了正确响应格式(默认是proto二进制,若后端返回JSON则需改用
decodeJson方法)
内容的提问来源于stack exchange,提问作者qaxdxzh3fi
相关产品推荐
相关产品推荐

