我正在编写一个 React Web 应用程序,我需要从预先签名的 S3 url 下载文件(或者如果需要,从 Fastapi 流式传输的 zip)。
我想使用内置的下载管理器 UI,现代浏览器必须显示下载正在进行中,就像 AWS S3 控制台 Web 应用程序一样,但我无法弄清楚。
这就是我要找的... 正在从 AWS S3 控制台下载
这是我当前的代码...
for (const asset of data) {
setCurrentAsset(data.indexOf(asset) + 1);
const s3Response = await fetch(asset.url);
if (!s3Response.ok) {
alert(`Failed to download: ${asset.name}`, );
break;
}
const chunks = [];
const reader = s3Response.body!.getReader();
const contentLength = +(s3Response.headers.get('Content-Length'))!;
let totalDownloaded = 0;
while (true) {
const { done, value } = await reader!.read();
if (done) {
break;
}
chunks.push(value);
totalDownloaded += value!.length;
setPercentThrottled(Math.round(totalDownloaded / contentLength * 100));
}
const url = window.URL.createObjectURL(new Blob(chunks));
const a = document.createElement('a');
a.href = url;
a.download = asset.name;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
}
}
所有块都流入后,资源就会出现在下载管理器中,但我想在下载管理器中查看下载进度。
此外,我的后端是Fastapi。我还使用其
StreamingResponse
类在一个文件中传输 zip
资源,但这并没有解决问题。
你所要求的是不可能的。
浏览器当前不会在其下载管理器中公开 API 以获取文件下载进度。当您使用
createObjectURL
时,该对象已在浏览器中下载并准备写入文件系统,因此下载管理器在这种情况下显示下载进度是没有意义的。此实现的唯一选择是在每次读取流后在网页中显示下载进度,就像您已经在做的那样。
您可能误解了 S3 控制台网站执行的工作。当您单击“下载”按钮时,它所做的就是生成自己的预签名 URL,并让浏览器下载它,就像您单击直接链接一样。您需要在 FastAPI 端点中使用 boto3 执行类似的操作。完成后,您可以将生成的 URL 传递回浏览器,然后执行类似于您在代码块底部已经执行的操作,创建一个锚元素(可能在影子 DOM 中,因此在页面),将 href 设置为您生成的 URL,然后单击它。