下载数据URL文件


126

我正在考虑制作一个完全基于JavaScript的zip / unzip实用程序,任何人都可以从浏览器访问该实用程序。他们只需将其zip直接拖到浏览器中,就可以下载其中的所有文件。他们还可以通过拖动单个文件来创建新的zip文件。

我知道最好在服务器端执行此操作,但是该项目只是为了使您开心一点。

如果我利用各种可用的方法,将文件拖放到浏览器中应该足够容易。(Gmail样式)

希望编码/解码应该可以。我已经看过一些as3 zip库,所以我确定我会满意的。

我的问题是最后下载文件。

window.location = 'data:jpg/image;base64,/9j/4AAQSkZJR....' 

这在Firefox中效果很好,但在chrome中效果不佳。

我可以使用chrome在chrome中将文件嵌入为图像<img src="data:jpg/image;ba.." />,但文件不一定是图像。它们可以是任何格式。

谁能想到其他解决方案或某种解决方法?


不幸的是,当前的支持是有限的
Casebash 2013年

Answers:


42

想法:

  • 尝试<a href="data:...." target="_blank">(未经测试)

  • 使用downloadify而不是数据URL(同样适用于IE)


@jcubic感谢您指出无效链接。新的下载位置似乎是github.com/dcneiner/Downloadify
Pekka

如果您不能使用Flash,但正在运行Java服务器端组件,则可以使用以下代码:github.com/suprememoocow/databounce。它使用Servlet从客户端“反弹”数据。在其他服务器端技术(例如Python,ASP.NET等)中执行相同的技巧相当容易
Andrew Newdigate

有没有办法不用闪光灯吗?除IE之外,所有浏览器的数据URL以及IE的某种ActiveX foo?(通过这种方式,我设法在没有Flash的情况下播放音乐:适用于IE和ActiveX的所有浏览器的HTML5音频,适用于IE。)
panzi 2012年

Downloadify期望浏览器中有Flash Player。如果用户没有flash播放器,那么文件不会下载
JeevanandanĴ

186

如果您还想给文件提供建议的名称(而不是默认的“下载”),则可以在Chrome,Firefox和某些IE版本中使用以下名称:

function downloadURI(uri, name) {
  var link = document.createElement("a");
  link.download = name;
  link.href = uri;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  delete link;
}

以下示例说明了它的用法:

downloadURI("data:text/html,HelloWorld!", "helloWorld.txt");

6
您可以使用- link.click()而不是-function简化该操作eventFire... jsfiddle.net/ARTsinn/Ezx5m
yckart 2013年

3
不错的解决方案。但是链接变成了什么?
webshaker 2014年

6
变量“ link”超出了函数末尾的范围(请注意,我们从未将其添加到dom中),因此不久后将被垃圾回收。
owencm

8
这仅适用于Chrome。如果您希望它在Firefox / IE中运行,请查看@MartinoDino的答案。
TrueWill

1
我尝试按照这里的建议使用download.js,它似乎可以工作。:)
joaorodr84

53

function download(dataurl, filename) {
  var a = document.createElement("a");
  a.href = dataurl;
  a.setAttribute("download", filename);
  a.click();
}

download("data:text/html,HelloWorld!", "helloWorld.txt");

要么:

function download(url, filename) {
fetch(url).then(function(t) {
    return t.blob().then((b)=>{
        var a = document.createElement("a");
        a.href = URL.createObjectURL(b);
        a.setAttribute("download", filename);
        a.click();
    }
    );
});
}

download("https://get.geojs.io/v1/ip/geo.json","geoip.json")
download("data:text/html,HelloWorld!", "helloWorld.txt");


不存在元素上的click事件:D不需要appendchild。
Zibri

1
是。您可以在创建元素“ a”后直接调用a.click(),然后设置a的href。
user1709076'1

过去直接调用a.click()无效,但可以与事件一起使用。现在他们都工作了。
Zibri

1
这在大多数现代浏览器中都有效,但是我要注意,添加到文档中然后删除是支持某些旧版浏览器所必需的。
owencm

3
每当dataUri太大时,都应使用第二种解决方案(取决于浏览器,但根据我的经验,Chrome不接受数兆字节的Uri)。另请参见stackoverflow.com/questions/38781968/…
Neuro5torm

27

想要分享我的经验,并帮助某些坚持下载功能的人无法在Firefox中使用,并更新了2014年的答案。

  // Construct the <a> element
  var link = document.createElement("a");
  link.download = thefilename;
  // Construct the uri
  var uri = 'data:text/csv;charset=utf-8;base64,' + someb64data
  link.href = uri;
  document.body.appendChild(link);
  link.click();
  // Cleanup the DOM
  document.body.removeChild(link);

4
不幸的是,它在Safari中不起作用。Safari似乎无法识别该download属性。无论如何,谢谢,这是我目前所能获得的。
莫里兹·彼得森

这导致窗口在IE 11中重定向到我的href值。prevetDefault(); 不会停止IE中的行为
b_dubb

1
谢谢,如果btoa还没有定义(例如,在节点支持的前端项目中) const btxt = new Buffer(text).toString('base64'); const uri = 'data:text/csv;charset=utf-8;base64,' + btxt + ';'
Ivan Borshchov

2
删除链接是没有意义的,它超出了下一行的范围,将被垃圾回收,它不是有效的删除目标。
macdja38

1
不需要document.body.appendChild ...参见我的答案stackoverflow.com/a/45905238/236062
Zibri

13

这是我在Firefox和Chrome中测试过的纯JavaScript解决方案,但在Internet Explorer中没有测试过:

function downloadDataUrlFromJavascript(filename, dataUrl) {

    // Construct the 'a' element
    var link = document.createElement("a");
    link.download = filename;
    link.target = "_blank";

    // Construct the URI
    link.href = dataUrl;
    document.body.appendChild(link);
    link.click();

    // Cleanup the DOM
    document.body.removeChild(link);
    delete link;
}

迄今为止的跨浏览器解决方案:

downloadify->需要Flash

databounce->在IE 10和11中测试过,对我不起作用。需要Servlet和一些自定义项。(错误地检测到导航器。我必须在兼容模式下设置IE进行测试,在servlet中设置默认字符集,为绝对路径使用具有正确servlet路径的JavaScript选项对象...)对于非IE浏览器,它将在同一窗口中打开文件。

download.js-> http://danml.com/download.html另一个类似但未经测试的库。声称是纯JavaScript,不需要servlet或Flash,但在IE <= 9上不起作用。


download.js相当不错。只是对IE11进行了快速检查,它可以工作。非常感谢!
Ricky Jiao

12

有几种解决方案,但是它们依赖于HTML5,并且尚未在某些浏览器中完全实现。下面的示例已在Chrome和Firefox中测试(部分有效)。

  1. 具有保存到文件支持的画布示例。只需将您设置document.location.href为数据URI。
  2. 锚下载示例。它用于<a href="your-data-uri" download="filename.txt">指定文件名。

3
画布示例导致404
KarelBílek'15

下载属性对我来说很有效,适用于chrome和移动Safari浏览器中的pdf数据网址。
bbsimonbb '18

7

结合@owencm和@ Chazt3n的答案,此功能将允许从IE11,Firefox和Chrome下载文本。(对不起,我无权访问Safari或Opera,但请尝试添加注释,并且可以使用。)

initiate_user_download = function(file_name, mime_type, text) {
    // Anything but IE works here
    if (undefined === window.navigator.msSaveOrOpenBlob) {
        var e = document.createElement('a');
        var href = 'data:' + mime_type + ';charset=utf-8,' + encodeURIComponent(text);
        e.setAttribute('href', href);
        e.setAttribute('download', file_name);
        document.body.appendChild(e);
        e.click();
        document.body.removeChild(e);
    }
    // IE-specific code
    else {
        var charCodeArr = new Array(text.length);
        for (var i = 0; i < text.length; ++i) {
            var charCode = text.charCodeAt(i);
            charCodeArr[i] = charCode;
        }
        var blob = new Blob([new Uint8Array(charCodeArr)], {type: mime_type});
        window.navigator.msSaveOrOpenBlob(blob, file_name);
    }
}

// Example:
initiate_user_download('data.csv', 'text/csv', 'Sample,Data,Here\n1,2,3\n');

1

对于在IE中有问题的任何人:

请在此处通过Yetti在上面添加答案: 在IE中本地保存画布

dataURItoBlob = function(dataURI) {
    var binary = atob(dataURI.split(',')[1]);
    var array = [];
    for(var i = 0; i < binary.length; i++) {
        array.push(binary.charCodeAt(i));
    }
    return new Blob([new Uint8Array(array)], {type: 'image/png'});
}

var blob = dataURItoBlob(uri);
window.navigator.msSaveOrOpenBlob(blob, "my-image.png");

0

您的问题实质上归结为“并非所有浏览器都支持”。

您可以尝试一种解决方法,并从Flash对象提供未压缩的文件,但随后您将失去纯JS的纯度(无论如何,我不确定当前是否可以在没有某种Flash解决方法的情况下将文件“拖入浏览器” -可能是HTML5功能吗?)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.