如何为预签名Post上传的文件添加自动SHA1校验和?
解决S3预签名POST上传后无SHA1校验和的问题
问题出在对S3预签名POST表单的校验和字段逻辑理解有误:预签名POST不支持让S3自动计算校验和,x-amz-checksum-algorithm字段在这里无法触发S3的自动计算逻辑,必须由客户端预先计算SHA1哈希值并提交对应的x-amz-checksum-sha1字段,才能让S3将其作为元数据存储。
结合你不需要将SHA1作为上传条件的需求,调整代码如下:
1. 修改Python预签名POST生成代码
移除原有的校验和算法字段与条件,添加允许客户端提交x-amz-checksum-sha1字段的规则:
import boto3 client = boto3.client("s3", config=...) presigned_post = client.generate_presigned_post( Bucket="my_bucket", Key="my_key", Conditions=[ # 允许客户端提交任意值的x-amz-checksum-sha1字段,不作为上传限制 ["starts-with", "$x-amz-checksum-sha1", ""], ], )
2. 前端计算SHA1并追加到表单
在上传前预先计算文件的SHA1哈希值(Base64编码),并添加到FormData中:
// 计算文件的SHA1哈希(Base64编码) async function calculateSHA1(file) { const arrayBuffer = await file.arrayBuffer(); const hashBuffer = await crypto.subtle.digest('SHA-1', arrayBuffer); const hashArray = Array.from(new Uint8Array(hashBuffer)); return btoa(String.fromCharCode(...hashArray)); } // 上传逻辑 const formData = new FormData(); const fields = uploadInfo.fields; Object.keys(fields).forEach((field) => { formData.append(field, fields[field]); }); // 计算SHA1并添加到表单 const sha1Hash = await calculateSHA1(contents); formData.append('x-amz-checksum-sha1', sha1Hash); formData.append('file', contents); await fetch(uploadInfo.url, {method: "POST", body: formData});
关键说明
- S3的预签名POST表单中,只有当客户端提交
x-amz-checksum-<algorithm>格式的字段(如x-amz-checksum-sha1)并提供有效哈希值时,S3才会将其作为文件元数据存储。 - 原代码中的
x-amz-checksum-algorithm字段仅适用于PUT请求或直接S3 API POST请求(非预签名),用于触发S3自动计算校验和,预签名POST不支持该逻辑。 - 调整后的代码中,
["starts-with", "$x-amz-checksum-sha1", ""]条件允许客户端提交任意SHA1值,不会将其作为上传的强制校验条件,仅作为附加元数据存储。
上传完成后,你可以在S3控制台的文件"属性"->"元数据"中看到x-amz-checksum-sha1字段,通过head_object等API请求也能获取到该值。
内容的提问来源于stack exchange,提问作者Mugen
相关产品推荐
相关产品推荐

