XML 使用适用于 JavaScript v3 的 AWS SDK 完成到 S3 的分段上传时出错
XML error completing a multi-part upload to S3 with AWS SDK for JavaScript v3
S3 的分段上传分为 3 个步骤:
- 开始分段上传
- 上传片段
- 完成分段上传
使用AWS SDK for JavaScript v3(正好v3.22),前两步成功:
UploadId
来自于初始化
- 每个上传的部分都带有完成
ETag
所需的
上传。
问题来自请求上传完成,这是通过以下方式完成的:
const completeParams: CompleteMultipartUploadCommandInput = {
Bucket,
Key,
UploadId,
MultipartUpload: { Parts },
};
return client.send(new CompleteMultipartUploadCommand(completeParams));
其中 Parts
是按 PartNumber
排序的有效 CompletedPart
对象数组。
正在分析网络调用,请求完成到
https://{Bucket}.s3.{Location}.scw.cloud/{Key}?uploadId={UploadId}&x-id=CompleteMultipartUpload
注意:用占位符替换了敏感数据,但它们是预期值。
AWS SDK生成的body是:
<?xml version="1.0" encoding="UTF-8"?>
<CompletedMultipartUpload xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Part>
<ETag>"610c4..."</ETag>
<PartNumber>1</PartNumber>
</Part>
<Part>
<ETag>"2edb4..."</ETag>
<PartNumber>2</PartNumber>
</Part>
</CompletedMultipartUpload>
注意:仅显示每个 ETag 的前 5 个字符,以表明它们不同并且来自上传部分。
但是S3的回答是:
The XML you provided was not well-formed or did not validate against our published schema.
通话顺序:
阅读extensive documentation,有一个微妙的区别:XML的根元素应该是CompleteMultipartUpload
而不是CompletedMultipartUpload
,但是XML 由 AWS SDK 生成,我希望它是正确的。
有什么问题吗?
问题
这是一个open issue at aws-sdk-js-v3 official repository.
该错误确实是 XML 元素上的拼写错误。它必须是 CompleteMultipartUpload
而不是 CompletedMultipartUpload
(额外的 d)。
解决方法
使用替换无效 XML 标记的中间件,如下所示:
const patchS3CompleteMultipartUpload = (client: S3Client): void => {
client.middlewareStack.add(
(next, _context) => (args: any) => {
if ('string' === typeof args.request?.body && args.request.body.includes('CompletedMultipartUpload')) {
args.request.body = args.request.body.replace(/CompletedMultipartUpload/g, 'CompleteMultipartUpload');
}
return next(args);
},
{
step: 'build',
priority: 'high',
}
);
};
S3 的分段上传分为 3 个步骤:
- 开始分段上传
- 上传片段
- 完成分段上传
使用AWS SDK for JavaScript v3(正好v3.22),前两步成功:
UploadId
来自于初始化- 每个上传的部分都带有完成
ETag
所需的 上传。
问题来自请求上传完成,这是通过以下方式完成的:
const completeParams: CompleteMultipartUploadCommandInput = {
Bucket,
Key,
UploadId,
MultipartUpload: { Parts },
};
return client.send(new CompleteMultipartUploadCommand(completeParams));
其中 Parts
是按 PartNumber
排序的有效 CompletedPart
对象数组。
正在分析网络调用,请求完成到
https://{Bucket}.s3.{Location}.scw.cloud/{Key}?uploadId={UploadId}&x-id=CompleteMultipartUpload
注意:用占位符替换了敏感数据,但它们是预期值。
AWS SDK生成的body是:
<?xml version="1.0" encoding="UTF-8"?>
<CompletedMultipartUpload xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Part>
<ETag>"610c4..."</ETag>
<PartNumber>1</PartNumber>
</Part>
<Part>
<ETag>"2edb4..."</ETag>
<PartNumber>2</PartNumber>
</Part>
</CompletedMultipartUpload>
注意:仅显示每个 ETag 的前 5 个字符,以表明它们不同并且来自上传部分。
但是S3的回答是:
The XML you provided was not well-formed or did not validate against our published schema.
通话顺序:
阅读extensive documentation,有一个微妙的区别:XML的根元素应该是CompleteMultipartUpload
而不是CompletedMultipartUpload
,但是XML 由 AWS SDK 生成,我希望它是正确的。
有什么问题吗?
问题
这是一个open issue at aws-sdk-js-v3 official repository.
该错误确实是 XML 元素上的拼写错误。它必须是 CompleteMultipartUpload
而不是 CompletedMultipartUpload
(额外的 d)。
解决方法
使用替换无效 XML 标记的中间件,如下所示:
const patchS3CompleteMultipartUpload = (client: S3Client): void => {
client.middlewareStack.add(
(next, _context) => (args: any) => {
if ('string' === typeof args.request?.body && args.request.body.includes('CompletedMultipartUpload')) {
args.request.body = args.request.body.replace(/CompletedMultipartUpload/g, 'CompleteMultipartUpload');
}
return next(args);
},
{
step: 'build',
priority: 'high',
}
);
};