您指定的 Content-MD5 对于分段上传无效



我正在使用 awd-sdk for nodejs 并有一个有效的上传。

const checksum = await this.getChecksum(path);
const payload: S3.PutObjectRequest = {
Bucket: bucket,
Key: key,
Body: fs.createReadStream(path),
ContentMD5: checksum,
};
return this.s3.upload(payload).promise();

这段代码非常适合小文件,并利用了自动验证文件完整性的ContentMD5

内容-MD5 根据 RFC 1864 对消息(不带标头(进行 base64 编码的 128 位 MD5 摘要。此标头可用作消息完整性检查,以验证数据是否与最初发送的数据相同。尽管它是可选的,但我们建议使用 Content-MD5 机制作为端到端完整性检查。有关 REST 请求身份验证的详细信息,请参阅 REST 身份验证。 https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html

但是,它不适用于分段上传。

The Content-MD5 you specified is invalid for multi-part uploads.

这是有道理的,因为我们逐块发送文件,但是,我想知道我应该如何将此功能用于分段上传?

我也面临这个问题并进行了多次测试。终于找到了答案,用自己的方式验证了。如果你们知道更好的方法,请在这里告诉我。

话虽如此,这就是我解决问题的方法。

创建 S3 客户端时,必须按如下方式创建它。

const s3 = new AWS.S3({ computeChecksums: true });

然后,您可以定义 s3 上传参数,如下所示

var fileData = Buffer.from(fileContentString, 'binary');
var s3params = {
Bucket: bucketName,
Key: folderName + "/" + fileName,
ContentType: 'binary',
Body: fileData
};

然后按如下方式上传。

await s3.upload(s3params).promise()
.then(data => {
// use this log to verify whether the md5 checksum was verified
console.log(`File uploadedd successfully ${JSON.stringify(data)}`);
// handle success upload
})
.catch(error => {
//handle the error
});

上传成功后,这是我验证其工作的方式。

  • 检查 S3 中的项目。在文档详细信息的"对象概述"部分中,选中 E 标记。您应该看到类似这样的内容 7e35f58f134d8914604c9fc6c35b2db7-9。- 后面的这个数字表示上传了多少个部分。对于较大的文件,应有一个大于 1 的数字。在本例中为 9。

  • 在控制台中检查日志。(上面代码中带有注释的日志。你会看到如下所示的内容。

    {
    "Location": "https://bucketname.s3.region.amazonaws.com/folderName/fileName",
    "Bucket": "bucketName",
    "Key": "folderName/fileName",
    "ETag": ""7e35f58f134d8914604c9fc6c35b2db7-9""
    }
    
  • 如果您正在调试,可以通过打印 s3 上传请求来进一步测试它。

    var uploadRequest = s3.upload(s3params);
    console.log(`S3 Request ${JSON.stringify(uploadRequest)}`);
    

    这将打印 s3 客户端配置。检查"计算校验和"是否设置为 true。

我也尝试使用 s3.putObject 进行验证。但是当我打印请求时,它没有在标头中显示 md5Checksum 配置,因为它是预期的。此外,当我尝试以与上传第三点相同的方式记录整个对象时,它给了我循环 JSON 字符串错误。所以我只打印了httpRequest。

var uploadRequest = s3.putObject(s3params);
console.log(`S3 Request ${JSON.stringify(uploadRequest.httpRequest)}`
//Following gives the JSON stringifying cyclic issue
//console.log(`S3 Request ${JSON.stringify(uploadRequest)}`);

如果有人可以告诉如何执行此操作并使用 putObject 进行验证,请表示感谢。

最新更新