如何使用Protobuf实现文件上传?后端解析报错求助
问题原因及解决方案
核心问题
你前端传递的file_content格式不符合Protobuf JSON规范:
- Protobuf的
bytes类型在JSON序列化时必须是Base64编码的字符串,但你直接将Uint8Array赋值给file_content,经JSON.stringify后会被序列化为类似{0: 255, 1: 216, ...}的对象结构,后端protojson.Unmarshal解析时无法识别这种格式,因此抛出invalid value for bytes type: {错误。
前端修复方案
将文件内容转换为Base64编码的字符串后再赋值给file_content,修改handleFile代码如下:
const handleFile = (file: File) => { const reader = new FileReader(); reader.onload = (e) => { const result = e.target?.result as ArrayBuffer; const fileContent = new Uint8Array(result); // 将Uint8Array转换为Base64字符串 const base64Content = btoa(String.fromCharCode(...fileContent)); const newFileRequest: FileRequest = { file_content: base64Content, }; addImage(newFileRequest).then(() => { alert("finished"); }); }; reader.readAsArrayBuffer(file); };
补充实现方式
如果使用readAsDataURL,需要去掉前缀(如data:image/png;base64,)才能得到纯Base64内容:
const handleFile = (file: File) => { const reader = new FileReader(); reader.onload = (e) => { const dataUrl = e.target?.result as string; const base64Content = dataUrl.split(',')[1]; const newFileRequest: FileRequest = { file_content: base64Content, }; addImage(newFileRequest).then(() => { alert("finished"); }); }; reader.readAsDataURL(file); };
后端代码验证
你的后端解析流程是正确的:先将请求体解析为JSON RawMessage,再通过protojson.Unmarshal反序列化为Protobuf消息,只要前端传递符合规范的Base64字符串,就能正常解析。
内容的提问来源于stack exchange,提问作者Tim Baker
相关产品推荐
相关产品推荐

