在Firefox中以编程方式触发文件下载的JavaScript

13

我有一个存在内存中的数据URI,我希望用户能够将其下载。

这个JSFiddle在Chrome浏览器中可以工作,但在Firefox浏览器中无法正常工作: http://jsfiddle.net/6W2TY/

当您点击运行时,它会在Chrome中下载微小的图像,但在Firefox中没有任何反应。有谁能帮我理解为什么它在Firefox中不起作用,并告诉我需要做什么才能使其正常工作?

谢谢!


7
小提琴链接无法使用。您能否为了记录的缘故在问题中发布代码? - hitautodestruct
2个回答

36

我知道这是一个老帖子,但是当我在FF中遇到下载文件的类似问题时,我找到了它。虽然这可能在提问时在FF中无效,但现在可以使用。

a = document.createElement('a');
document.body.appendChild(a);
a.download = name;
a.href = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAABWSURBVDhPY0xISPh//0UOA7mAiVyNMH2jBjAwkBQGjD9KGBTEJ6OEO0kG2NvbMwCjnXwDsEU5SS5ANuDhjRCGJbPFSQsDdBfIyMhQZgDIQLK9QLWkDABPsQw5I+5qmAAAAABJRU5ErkJggg==";
a.click();

从原始的代码中所作的更改如下:

  1. 添加了调用 document.body.appendChild(a); 的语句;
  2. triggerEvent() 修改为 a.click()

这里是更新后的代码示例: http://jsfiddle.net/70f91ao7/6/


1
关键是将其附加到DOM上,以使此方法在Firefox下起作用。 - Beeno Tung
这可能已经不再起作用了。 - Daut
为什么需要将元素添加到DOM中?在Chrom (96)上,即使不添加也可以正常工作。 - maxicarlos08

12
你正在使用新的(html5)下载属性。据我所知,目前只有Chrome支持,而Firefox还不支持。 更新3-2018
现在,几乎所有主流浏览器都支持此功能(不支持IE)。

替代方法:使用location.href

另一种强制下载的方法是将用户重定向到图像,如下所示:

// generate the image
var img = ""

// then call a function maybe onClick or something
downloadImage(img);

function downloadImage(data) {
    location.href = "data:application/octet-stream;base64," + data;
}

或者简短版

location.href = "data:application/octet-stream;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAABWSURBVDhPY0xISPh//0UOA7mAiVyNMH2jBjAwkBQGjD9KGBTEJ6OEO0kG2NvbMwCjnXwDsEU5SS5ANuDhjRCGJbPFSQsDdBfIyMhQZgDIQLK9QLWkDABPsQw5I+5qmAAAAABJRU5ErkJggg=="

替代方案:服务器端

作为一种替代方案,如果您正在服务器端处理图像,则可以通过设置content-disposition头来强制下载。

PHP示例

header('Content-Disposition: attachment; filename="image.png"');

我正在构建我想让用户能够在客户端下载的图像。有没有办法让用户在FF中下载我拥有data-uri的客户端图像?看起来download属性在Chrome上已经存在一年多了,所以我不确定FF是否有任何计划支持它。 - asutherland
我添加了我的答案,包括仅使用javascript的替代方案。这是你可以使用的吗? - Bart
很不幸,location.href选项意味着该文件没有正确的MIME类型,我无法将默认文件名设置为任何合理的名称,有什么解决办法吗?尽管这非常有帮助,但我仍将其标记为答案。谢谢。 - asutherland
我不知道你是否看到了这个,但我能想到的唯一解决方案(变通方法/黑客)是将图像发送回服务器并再次返回正确的标头。这样才能设置MIME类型和文件名。 - Bart
注意:此方法可能触发 'beforeunload' 事件。 - Eduard Kolosovskyi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接