7

我正在使用以下代码在 JavaScript 中保存文件:

var a = document.createElement('a');
a.href = URL.createObjectURL(new Blob(['SOME DATA']));
a.download = 'some.dat';
a.click();

下载文件后,我想撤销 URL(使用 URL.revokeObjectURL)。什么时候这样做是安全的?

我可以在打电话后立即撤销它a.click()(这似乎有效,但我不确定它是否安全)?ina的点击事件监听器?有没有办法让点击事件监听器在默认操作之后运行?

4

2 回答 2

3

a.click()on a DOM element 模拟对元素的点击,而不是传播点击事件,因此它直接发送到浏览器。我相信使用计时器将 URL 对象的撤销转移到另一个事件周期会更安全一些:

setTimeout(function() {
 URL.revokeObjectURL(a.href);
}, 0);
于 2016-05-15T16:39:42.687 回答
1

经过一些试验,似乎 Chrome 和 Safari 在单击元素后立即撤消时都能够下载 2GB 的文件。Firefox 能够在浏览器停止运行之前下载 600MB 的文件。

这是我用来下载大文件的方法:

const a = document.createElement('a');
const buffer = new ArrayBuffer(2_000_000_000);
const view = new Uint8Array(buffer);
for(let i=0; i<view.length; i++) {
    view[i] = 255;
}
a.href = URL.createObjectURL(new Blob([buffer]));
a.download = 'some.dat';
a.click();
URL.revokeObjectURL(a.href);

规范没有特别提到在撤销 url 时中止现有的流,所以理论上这样做会很好。

但是,为了安全起见,我会在几秒钟后使用 撤销 url setTimeout(),或者如果从特定屏幕启动下载,您可以添加逻辑以在用户离开该屏幕后撤销它。

一旦您的域的最后一页关闭,浏览器也会自动撤销对象 url,因此根据您的情况,根本不撤销 url 也可能是一个可行的解决方案。

于 2022-02-17T20:29:10.103 回答