【问题标题】:Handling large file downloads with javascript使用 javascript 处理大文件下载
【发布时间】:2019-06-11 11:20:03
【问题描述】:

我有一台服务器托管非常大的文件:> 50GB。到目前为止,这些文件只是通过浏览器正常下载。 (<a href="...">)
问题是,很多时候这些都是通过缓慢/不可靠的连接下载的,如果下载失败,它们必须从头开始。
作为对此的解决方案,我想在浏览器中创建一个替代下载器,其中每个下载的块都使用 javascript 保存到一些临时存储中,如果下载失败,则允许继续下载。

mega.nz 是使用类似内容的一个很好的例子。下载是用 javascript 处理的,当整个文件下载到一个临时位置时,浏览器会显示经典的文件下载对话框,它实际上是引用一个 blob url。 我想出了一些解决方案,但困难的部分是我需要支持 FF、Chrome 和 IE 11+。

解决方案 #1) 获取 + 文件系统 API + HTTP Range 标头
我使用fetch() 并将结果流式传输到FileWriter。如果在任何时候下载失败,我可以检查文件中写入了多少字节,并在下一个fetch() 上使用Range 标头。下载完成后,我可以得到一个类似filesystem:http://some-url/file 的网址,我可以将其分配为href 标记的a 属性,并设置download 选项。我发送了一个click() 事件,文件几乎立即下载。整个文件不会加载到内存中,因此它可以处理非常大的文件,但这种方法仅适用于 Chrome。我知道 FileSystem API 有一个使用 indexedDB 的 polyfill,但是当我需要生成 url 时,它会给我一个 blob,它会加载到内存中。写入还将整个值加载到内存中,附加到它,然后将其写回。 (效率低下,不适用于大文件)

解决方案 #2) 服务工作者 + IndexedDB
使用服务人员,我可以劫持fetch 事件,并发送回我想要的任何数据。我可以使用它来实现将文件保存到 IndexedDB,并从那里逐块提供它们,如果我使用正确的逻辑创建 ReadableStream,则无需将整个内容加载到内存中。

解决方案 #3) Flash(Actionscript)
Mega 似乎使用一些基于 Flash 的下载器作为旧浏览器的后备方案,还没有研究过,但也许这对于 IE 来说是一个可行的解决方案。

解决方案 #4) ActiveX
再次是 IE 的可能解决方案。是否可以使用 ActiveX 将数据直接流式传输到文件系统而不将其加载到内存中?

到目前为止,我缺少对 IE 以及未启用服务工作者的 FF 版本的支持,例如 Firefox ESR。 IE 有 IndexedDB,但为了下载数据,我必须创建一个包含整个文件的 blob,然后将其加载到内存中

我还有什么遗漏的吗?还有其他方法可以实现吗? 注意:很遗憾,浏览器扩展是不受限制的。

【问题讨论】:

    标签: flash activex service-worker indexeddb html5-filesystem


    【解决方案1】:

    我建议使用Background Fetch API,但需要注意的是,目前它仅在 Chrome 74+(以及相应的 Edge 预览版)中受支持。它专为您的用例而设计。

    我可以想象在支持时使用它,然后在不支持它的浏览器上使用替代方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-11
      • 1970-01-01
      • 2018-04-06
      • 2019-08-11
      • 1970-01-01
      • 2019-08-14
      • 2010-12-27
      • 2017-01-30
      相关资源
      最近更新 更多