我有一台托管非常大文件的服务器:> 50GB。到目前为止,这些文件通常只是通过浏览器下载的。 (<a href="...">
)
问题是,很多时候这些文件是通过慢速/不可靠的连接下载的,如果下载失败,则必须从头开始。
作为解决方案,我想在浏览器中创建一个备用下载器,其中每个下载的块都使用javascript保存到某个临时存储中,从而允许下载失败后恢复下载。
mega.nz是使用相似内容的一个很好的例子。下载是使用javascript处理的,当整个文件下载到一个临时位置时,浏览器将显示经典文件下载对话框,该对话框实际上是在引用Blob网址。 我已经提出了一些解决方案,但是困难的部分是我需要支持FF,Chrome和IE 11 +。
解决方案#1)获取+文件系统API + HTTP范围标头
我使用fetch()
并将结果流式传输到FileWriter
中。如果任何时候下载失败,我可以检查文件中写入了多少字节,并在下一个Range
上使用fetch()
标头。下载完成后,我将获得一个类似filesystem:http://some-url/file
的URL,可以将其设置为a
标签的href
标签的download
属性。我发送了一个click()
事件,该文件几乎是立即下载的。整个文件不会加载到内存中,因此可以处理非常大的文件,但是此方法仅适用于Chrome。我知道有一个使用indexedDB的FileSystem API的polyfill,但是当我需要生成url时,它将给我一个blob,该blob已加载到内存中。同样,写操作会将整个值加载到内存中,追加到内存中,然后再写回。 (效率很高,并且不适用于大文件)
解决方案2)服务人员+ IndexedDB
与服务人员一起,我可以劫持fetch
事件,并发回我想要的任何数据。我可以使用它来实现将文件保存到IndexedDB,并从那里逐块提供文件,而如果我使用正确的逻辑制作ReadableStream
,则不会将整个文件加载到内存中。
解决方案3) Flash(操作脚本)
Mega似乎使用一些基于Flash的下载器作为旧浏览器的后备,尚未研究过,但这也许是IE的可行解决方案。
解决方案4) ActiveX
再次是IE的可能解决方案。可以使用ActiveX直接将数据流传输到文件系统而无需将其加载到内存中吗?
到目前为止,我缺少对IE和未启用服务工作者的FF版本的支持,例如Firefox ESR。 IE具有IndexedDB,但是为了下载数据,我必须制作一个包含整个文件的Blob,并将其加载到内存中
还有其他我想念的东西吗?还有其他方法可以实现吗? 注意:不幸的是,浏览器扩展超出了限制。
答案 0 :(得分:0)
我建议使用Background Fetch API,但需要注意的是,目前Chrome 74+(以及相应的Edge预览版本)仅支持该功能。它是为您的用例设计的。
我可以想象在支持的情况下使用它,然后在不支持它的浏览器上使用替代方法。