@dandavis
如果有人可以演示一种机械方法来确定提示后用户对任何文件的操作,我会很乐意支付 10 倍的赏金!
你准备好了吗?因为这里有一个 hacky 解决方案?
我的 StreamSaver 库不要使用 blob 下载带有 a[download] 的文件。它使用 service worker 通过模拟服务器如何使用 content-disposition 附件标头处理下载来将内容流式传输到光盘。
evt.respondWith(
new Response(
new ReadableStream({...})
)
)
现在您无法确切知道用户在对话框中按了什么,但您有一些关于流的信息。
如果用户在对话框中按取消或中止正在进行的下载,则流将获取也流产了。
保存按钮比较复杂。但是让我们从流桶 highWaterMark 可以告诉我们的内容开始。
在我的torrent example 中,我记录了writer.desiredSize。这与它愿意接收多少数据有关。当您向流中写入内容时,它会降低所需的大小(无论是计数策略还是字节策略)。如果它从未增加,则意味着用户可能已暂停下载。当它低于 0 时,您写入的数据比用户要求的要多。
你所做的每一个块写入都会返回一个承诺
writer.getWriter().write(uint8).then(() => {
// Chunk have been sent to the destination bucket
// and desiredSize increase again
})
当桶未满时,该承诺将解决。但这并不意味着该块已被写入磁盘,它仅意味着该块已从一个流传递到另一个流(从写入 -> 可读 -> 响应),并且通常会在开始时这样做当另一个更早的块被写入磁盘时。
如果空洞数据可以放入存储桶(内存)中,甚至在用户做出选择之前写入流就有可能完成
将存储桶大小调整为小于数据可以提供帮助
所以你可以假设
- 下载开始
- 结束
- 并暂停
但您无法确定,因为您没有收到任何事件(除了关闭流的中止)
请注意,如果您不支持 Transferable streams,则 torrent 示例不会显示正确的大小,但如果您在 service worker 中执行所有操作,则可以解决此问题。 (而不是在主线程中进行)
检测流何时结束非常简单
readableStream.pipeTo(fileStream).then(done)
对于将来的参考,WICG/native-file-system 可能会授予您将文件写入光盘的权限,但它必须先解决提示对话框承诺,然后才能继续,并且可能正是用户要求的内容
有将blob 保存为流的示例,如果您有兴趣,还有更多multiple blob's as a zip