如何在浏览器内置的下载管理器中显示下载进度

问题描述 投票:0回答:1

我正在编写一个 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
资源,但这并没有解决问题。

javascript reactjs typescript amazon-s3 fastapi
1个回答
0
投票

你所要求的是不可能的。

浏览器当前不会在其下载管理器中公开 API 以获取文件下载进度。当您使用

createObjectURL
时,该对象已在浏览器中下载并准备写入文件系统,因此下载管理器在这种情况下显示下载进度是没有意义的。此实现的唯一选择是在每次读取流后在网页中显示下载进度,就像您已经在做的那样。

您可能误解了 S3 控制台网站执行的工作。当您单击“下载”按钮时,它所做的就是生成自己的预签名 URL,并让浏览器下载它,就像您单击直接链接一样。您需要在 FastAPI 端点中使用 boto3 执行类似的操作。完成后,您可以将生成的 URL 传递回浏览器,然后执行类似于您在代码块底部已经执行的操作,创建一个锚元素(可能在影子 DOM 中,因此在页面),将 href 设置为您生成的 URL,然后单击它。

© www.soinside.com 2019 - 2024. All rights reserved.