我可以在网上找到很多关于如何使用 aws-sdk V2 跟踪上传到 S3 的进度的资源,监听事件如下:
.on('httpUploadProgress', event => {}
但是自从我将 aws-sdk 更新到 V3 后,就不再有监听器了。我相信我现在必须使用中间件功能,但我尝试了一些方法但没有成功。我还深入研究了 API 参考文档 和 github 存储库,但没有成功。
我当前的代码是这样的:
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
export const UploadToS3 = (credentials, fileData) => {
const s3 = new S3Client({
region: credentials.region,
credentials: {
accessKeyId: credentials.access_key,
secretAccessKey: credentials.secret_key,
sessionToken: credentials.session_token,
}
});
return new Promise((resolve) => {
s3.send(new PutObjectCommand({
Bucket: credentials.bucket,
Key: credentials.file,
Body: fileData,
}));
});
};
如有任何帮助,我们将不胜感激
我遇到了完全相同的问题(从 aws-sdk v2 切换到 v3),发现这是因为该库对所有 HTTP 请求使用 Fetch API,并且
Fetch
(尚)不支持跟踪上传进度
为了解决这个问题,我将
Fetch
至少换成了 XMLHttpRequest
请求,您可以通过在初始化 S3Client 时提供自定义 requestHandler来完成。
PUT
自定义请求处理程序只是从 @aws-sdk/fetch-http-handler 扩展
import { S3Client } from '@aws-sdk/client-s3';
const myHttpHandler = new MyHttpHandler();
myHttpHandler.onProgress$.subscribe(progress => {
const percentComplete = progress.progressEvent.loaded / progress.progressEvent.total * 100;
console.log('upload progress', percentComplete);
});
const myClient = new S3Client({
endpoint: this.configService.s3Api,
region: 'eu',
credentials: { ... },
requestHandler: myHttpHandler
});
。如果方法是
FetchHttpHandler
并且有一个正文(因此我们想要上传一些内容),它会使用自定义 XHR 处理程序 - 否则它只使用 PUT
类中的 Fetch
处理程序。
在 XHR 处理程序中,您可以将某些内容绑定到 XHR 处理程序的 super
事件 - 在我的例子中,我发出一个 rxjs progress
,我可以在自定义处理程序之外使用它。Subject
对我来说适用于分段上传,但需要修复一个错误(使用 @aws-sdk/client-s3 的 v3.438.0),因为 PUT 请求的响应标头未正确解析. 我变了
import { S3Client } from '@aws-sdk/client-s3';
import { XhrHttpHandler } from '@aws-sdk/xhr-http-handler';
import { Upload } from '@aws-sdk/lib-storage';
const s3Client = new S3Client({
requestHandler: new XhrHttpHandler({}),
});
const upload = new Upload({
client:s3Client,
params: {
bucket,
key,
},
});
upload.on("httpUploadProgress", (progress) => {
console.log(
progress.loaded, // Bytes uploaded so far.
progress.total // Total bytes. Divide these two for progress percentage.
);
});
await upload.done();
到
fetchHeaders.forEach((header) => {
const name = header.substr(0, header.indexOf(':') + 1);
const val = header.substr(header.indexOf(':') + 1);
if (name && val) {
transformedHeaders[name] = val;
}
});