156

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

我知道在服务器端做会更好,但这个项目只是为了好玩。

如果我利用各种可用的方法,将文件拖入浏览器应该很容易。(Gmail 风格)

编码/解码应该没问题。我看过一些 as3 zip 库,所以我相信我应该没问题。

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

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

这在 Firefox 中运行良好,但在 Chrome 中不行。

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

谁能想到另一种解决方案或某种解决方法?

4

12 回答 12

246

如果您还想为文件提供建议的名称(而不是默认的“下载”),您可以在 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");
于 2013-04-05T11:23:20.610 回答
96

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

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

或者:

function download(url, filename) {
  fetch(url)
    .then(response => response.blob())
    .then(blob => {
      const link = document.createElement("a");
      link.href = URL.createObjectURL(blob);
      link.download = filename;
      link.click();
  })
  .catch(console.error);
}

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

于 2017-08-27T13:02:18.613 回答
51

想法:

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

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

于 2010-10-12T15:24:33.177 回答
28

想分享我的经验并帮助那些坚持下载无法在 Firefox 中运行的人,并更新了 2014 年的答案。下面的代码片段将在 Firefox 和 chrome 中运行,它会接受一个文件名:

  // 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);
于 2014-12-04T01:28:31.750 回答
21

这是我在 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;
}

到目前为止发现的跨浏览器解决方案:

下载 -> 需要 Flash

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

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

于 2016-04-26T20:11:18.887 回答
13

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

  1. 支持保存到文件的画布示例。只需将您document.location.href的设置为数据 URI。
  2. 锚点下载示例。它用于<a href="your-data-uri" download="filename.txt">指定文件名。
于 2012-02-27T10:55:51.937 回答
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');
于 2017-01-13T03:17:09.747 回答
7

仅使用 HTML 就可以 100% 完全解决这个问题。 只需将href属性设置为"data:(mimetypeheader),(url)". 例如...

<a
    href="data:video/mp4,http://www.example.com/video.mp4"
    target="_blank"
    download="video.mp4"
>Download Video</a>

工作示例:JSFiddle 演示

因为我们使用数据 URL,所以我们可以设置表示要下载的数据类型的 mimetype。文档:

数据 URL 由四部分组成:前缀 (data:)、指示数据类型的 MIME 类型、可选的 base64 标记(如果非文本)和数据本身。(来源:MDN 网络文档:数据 URL。)

组件:

  • <a ...>: 链接标签。
  • href="data:video/mp4,http://www.example.com/video.mp4":在这里,我们将链接设置为data:带有预配置标题的 a video/mp4。紧随其后的是标头 mimetype。IE,对于.txt文件,它将是text/plain. 然后用逗号将它与我们要下载的链接分开。
  • target="_blank":这表示应该打开一个新选项卡,这不是必需的,但它有助于引导浏览器达到所需的行为。
  • download:这是您正在下载的文件的名称。
于 2021-01-06T21:34:01.547 回答
2

对于任何在 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");
于 2017-01-02T23:12:42.007 回答
2

如果您只需要实际执行下载操作,例如将其绑定到某个按钮,该按钮将在单击时动态生成 URL(例如在 Vue 或 React 中),您可以执行以下简单操作:

const link = document.createElement('a')
link.href = url
link.click()

就我而言,该文件已经正确命名,但filename如果需要,您可以设置它。

于 2021-04-16T03:36:05.430 回答
0

您的问题基本上归结为“并非所有浏览器都支持这一点”。

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

于 2010-10-12T15:25:03.177 回答
-1
export const downloadAs = async (url: string, name: string) => {
  const blob = await axios.get(url, {
    headers: {
      'Content-Type': 'application/octet-stream',
    },
    responseType: 'blob',
  });
  const a = document.createElement('a');
  const href = window.URL.createObjectURL(blob.data);
  a.href = href;
  a.download = name;
  a.click();
};
于 2021-04-19T12:28:57.120 回答