Cordova上传Google App Engine签名URL时Content-MD5不匹配问题
问题根因
你提交的Content-MD5编码格式不符合GCS要求:
GCS要求Content-MD5值为MD5原始16字节二进制数据的base64编码,但你当前是对32位的MD5十六进制字符串直接做base64编码,二者完全不同。
你报错信息中给出的无效MD5值ZWFmMjRlNmE0OTExMjRhMTllYmYxYzU2ODliOWIyZGE=,解码后就是你提到的正确MD5十六进制字符串eaf24e6a491124a19ebf1c5689b9b2da,直接验证了这个问题。
修复方案
需要同时修改签名生成逻辑和前端上传逻辑,保证两边传递的MD5编码一致且符合GCS规范:
1. PHP签名URL生成代码修复
将32位十六进制格式的MD5先转为二进制,再做base64编码:
$url = $object->signedUrl( new \DateTime("60 min"), [ "method" => "PUT", 'version' => 'v4', "contentType" => "application/octet-stream", "contentMd5" => base64_encode(hex2bin($md5)) // 新增hex2bin转二进制 ] );
2. Cordova上传代码修复
不要直接对十六进制MD5执行btoa,先将十六进制转为二进制字符串再做base64编码:
// 新增十六进制转标准base64工具函数 function hexToMd5Base64(hexStr) { return btoa( hexStr.match(/\w{2}/g) .map(hex => String.fromCharCode(parseInt(hex, 16))) .join('') ); } var uploadFileTransfer = new FileTransfer(); var options = new FileUploadOptions(); options.fileKey = "file"; options.httpMethod = "PUT"; options.fileName = "my_file.zip"; options.mimeType = "application/octet-stream"; options.headers = { "content-md5": hexToMd5Base64(fileMd5), // 替换原有的btoa逻辑 'content-type': 'application/octet-stream' } uploadFileTransfer.upload(file, url, success, fail, options);
注意事项
签名URL中指定的contentMd5参数值必须和上传请求头的content-md5完全一致,否则会出现签名校验失败或者MD5校验失败的问题。
内容的提问来源于stack exchange,提问作者DdD
相关产品推荐
相关产品推荐

