原生.click()不会触发Chrome 57中的Blob下载

时间:2017-03-13 15:06:43

标签: javascript html5 google-chrome dom-events

客户端Blob保存代码片段突然停止在Google Chrome中运行。相同的代码继续在Firefox中工作。该代码几乎与this answer中提供的代码完全相同。

var downloadLink = document.createElement("a");
var url = URL.createObjectURL(new Blob(["\ufeff", rows]));
downloadLink.href = url;
downloadLink.download = filename;

document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);

.click()上设置断点然后单步执行会导致文件按预期下载,但通常不会运行代码。我确实发现将.click()包裹在setTimeout中确实允许它成功,但只有在超时足够长时

var downloadLink = document.createElement("a");
var url = URL.createObjectURL(new Blob(["\ufeff", rows]));
downloadLink.href = url;
downloadLink.download = filename;

document.body.appendChild(downloadLink);
setTimeout(function() {
    downloadLink.click();
    document.body.removeChild(downloadLink);
}, duration);

,其中

Duration  |  Download
----------+----------
0 ms      |  Fail
1 ms      |  Fail
10 ms     |  Fail
100 ms    |  Fail
1000 ms   |  Succeed

我不确定问题是从版本57开始的,但我正在寻找有关如何在不诉诸setTimeout黑客的情况下改进Blob下载的任何信息或建议。

**编辑**

我应该清楚,Blob下载是由用户启动的按钮点击触发的,并不是在页面加载时无条件运行的代码段。

3 个答案:

答案 0 :(得分:1)

我正在使用57以及以下作品。您是否可以确认它对您有用,以确定它是否与此代码或页面中的其他内容有关。

<html>
<head>
<script>
    function download(filename, text) {
      var element = document.createElement('a');          
      var url = URL.createObjectURL(new Blob(['\ufeff', text]));

      element.id = 'downloadLink';
      element.href = url;
      element.download = filename;

      document.body.appendChild(element);

      var downloadLink = document.getElementById('downloadLink');
      downloadLink.click();

      document.body.removeChild(downloadLink);
    }
</script>
</head>
<body>
    <button onclick="download('test.txt', 'Hello this is a test')">Click Me</button>
</body>
</html>

答案 1 :(得分:1)

由于通过调用FileSaver,js saveAs函数替换了提供的下载代码,我决定查看FileSave代码,看看它与我的实现有何不同。

核心区别在于File Saver创建了一个锚节点,但是将它添加到DOM。删除一些无关的代码后,我将问题提炼为appendChild调用

工作代码

var downloadLink = document.createElement("a");
var url = URL.createObjectURL(blob);
downloadLink.href = url;
downloadLink.download = filename;

// document.body.appendChild(downloadLink);
downloadLink.click();

删除注释行会导致代码再次失败。

答案 2 :(得分:0)

如果它是一个计时问题,那么该文档可能尚未完成加载(因此设置超时足够长时间允许它)。相反,请尝试附加到您知道文档已完全加载的事件。

var downloadLink = document.createElement("a");
var url = URL.createObjectURL(new Blob(["\ufeff", rows]));
downloadLink.href = url;
downloadLink.download = filename;

document.body.appendChild(downloadLink);
document.onload = function() {
    downloadLink.click();
    document.body.removeChild(downloadLink);
};

注意代码在您提到的示例中有效的原因是因为用户触发了事件(提交表单)。