【发布时间】: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