使用Google Cloud Storage JSON API上传图片失败,文件损坏显示0B/2B求助
解决gapi.client.request上传图片损坏的问题
我之前也碰到过一模一样的情况,gapi.client.request在处理二进制文件上传时确实有不少坑——它内部会对请求体做额外的序列化处理,你直接传File对象再手动设置Content-Length,会和它的内部逻辑冲突,导致实际发送的内容长度完全不对,最终上传的文件变成0B或2B的损坏状态。
解决方案1:改用原生Fetch API(推荐,无需额外依赖)
既然你不想引入Node.js,原生Fetch完全能搞定,而且对二进制文件的支持更可靠:
const uploadUrl = `upload/storage/v1/b/${this.bucket}/o?uploadType=media&name=${encodeURIComponent(vBody.name)}`; fetch(uploadUrl, { method: 'POST', headers: { 'Authorization': `Bearer ${tok}`, 'Content-Type': vFiles[k].type // 这里绝对不要手动设置Content-Length,浏览器会自动计算并设置 }, body: vFiles[k] }) .then(res => res.json()) .then(res => { console.log('上传成功:', res); }) .catch(err => { console.error('上传失败:', err); });
为什么这个能行?因为浏览器的Fetch API会自动识别File对象作为请求体,正确处理二进制数据的传输,还会自动计算并设置Content-Length,不会像gapi.client那样对二进制内容做多余的序列化操作。
解决方案2:修复gapi.client的使用方式(不推荐,局限性大)
如果你一定要用gapi.client,得先把File对象转换成ArrayBuffer,再传给它,但步骤比较繁琐,而且对大文件友好度不高:
// 先把File转成ArrayBuffer const reader = new FileReader(); reader.onload = function(e) { const arrayBuffer = e.target.result; const zz = { path: `upload/storage/v1/b/${this.bucket}/o?uploadType=media&name=${encodeURIComponent(vBody.name)}`, method: "POST", headers: { "Authorization": `Bearer ${tok}`, "Content-Type": vFiles[k].type // 同样不要手动设置Content-Length }, body: arrayBuffer }; gapi.client.request(zz).then(res => { console.log(res); }); }; reader.readAsArrayBuffer(vFiles[k]);
这种方法虽然能解决问题,但比起Fetch还是麻烦不少,而且gapi.client在处理大文件时容易出现性能问题,所以更推荐用Fetch方案。
关键注意点
- 绝对不要手动设置
Content-Length:浏览器会根据请求体自动计算这个值,手动设置反而会因为gapi的内部处理导致长度不匹配,直接搞坏文件。 - gapi.client更适合处理JSON格式的API请求,二进制文件上传还是用原生Fetch或XMLHttpRequest更靠谱。
内容的提问来源于stack exchange,提问作者tjg92
相关产品推荐
相关产品推荐

