AWS S3预签名Post Policy使用x-amz-checksum-sha256遇400错误求解
解决S3预签名Post Policy上传时x-amz-checksum-sha256无效的问题
问题核心是你生成校验值的编码逻辑错误:S3要求x-amz-checksum-sha256的值是SHA256哈希原始二进制数据的Base64编码,但你当前的代码是先把哈希转成十六进制字符串,再对这个字符串做Base64编码,这完全不符合AWS的要求。
修正前端校验值生成代码
替换你生成校验值的部分,直接对SHA256的二进制哈希结果进行Base64编码,跳过十六进制转换步骤:
const fileBlob = new Blob([file]); const arrayBuffer = await fileBlob.arrayBuffer(); const hashBuffer = await crypto.subtle.digest("SHA-256", arrayBuffer); // 直接将二进制哈希转换为Base64 const base64Checksum = btoa(String.fromCharCode(...new Uint8Array(hashBuffer))); const postData = await backendAPICallToGetPresignedPost({base64Checksum}); const postForm = new FormData(); Object.keys(postData.fields).forEach((key) => { postForm.append(key, postData.fields[key]); }); postForm.append('x-amz-checksum-algorithm', 'SHA256'); postForm.append('x-amz-checksum-sha256', base64Checksum); postForm.append('file', file); // 移除请求头中的校验值字段,POST上传时通过表单字段提交即可 axios.post('S3-url', postForm);
额外说明
- 你的测试用例中,正确的Base64校验值应该是将十六进制字符串
1789f8b9f648498f5abcfe3c71b7fb4047143b431022d477d27a7acba64d2ca8转换为二进制后再Base64编码,结果为GHn4u/ZISY9avP48cbf7QEcUO0MBItR30noaysTSooA=,而不是你当前生成的十六进制字符串的Base64。 - 预签名Post上传时,
x-amz-checksum-*字段应该通过表单字段提交,不需要添加到请求头中,避免字段重复导致的校验失败。 - 后端代码逻辑无需修改,只要前端传入正确的Base64校验值即可。
内容的提问来源于stack exchange,提问作者neubee
相关产品推荐
相关产品推荐

