Html 没有链接的 JavaScript blob 文件名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19327749/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 14:22:39  来源:igfitidea点击:

JavaScript blob filename without link

javascripthtmldownloadblobhtml5-filesystem

提问by Ash Blue

How do you set the name of a blob file in JavaScript when force downloading it through window.location?

当通过 window.location 强制下载 blob 文件时,如何在 JavaScript 中设置它的名称?

function newFile(data) {
    var json = JSON.stringify(data);
    var blob = new Blob([json], {type: "octet/stream"});
    var url  = window.URL.createObjectURL(blob);
    window.location.assign(url);
}

Running the above code downloads a file instantly without a page refresh that looks like:

运行上面的代码会立即下载一个文件,而无需刷新页面,如下所示:

bfefe410-8d9c-4883-86c5-d76c50a24a1d

bfefe410-8d9c-4883-86c5-d76c50a24a1d

I want to set the filename as my-download.jsoninstead.

我想将文件名设置为my-download.json

回答by kol

The only way I'm aware of is the trick used by FileSaver.js:

我知道的唯一方法是FileSaver.js使用的技巧:

  1. Create a hidden <a>tag.
  2. Set its hrefattribute to the blob's URL.
  3. Set its downloadattribute to the filename.
  4. Click on the <a>tag.
  1. 创建隐藏<a>标签。
  2. 将其href属性设置为 blob 的 URL。
  3. 将其download属性设置为文件名。
  4. 点击<a>标签。

Here is a simplified example (jsfiddle):

这是一个简化的示例(jsfiddle):

var saveData = (function () {
    var a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    return function (data, fileName) {
        var json = JSON.stringify(data),
            blob = new Blob([json], {type: "octet/stream"}),
            url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = fileName;
        a.click();
        window.URL.revokeObjectURL(url);
    };
}());

var data = { x: 42, s: "hello, world", d: new Date() },
    fileName = "my-download.json";

saveData(data, fileName);

I wrote this example just to illustrate the idea, in production code use FileSaver.js instead.

我写这个例子只是为了说明这个想法,在生产代码中使用 FileSaver.js 代替。

Notes

笔记

  • Older browsers don't support the "download" attribute, since it's part of HTML5.
  • Some file formats are considered insecure by the browser and the download fails. Saving JSON files with txt extension works for me.
  • 较旧的浏览器不支持“下载”属性,因为它是 HTML5 的一部分。
  • 浏览器认为某些文件格式不安全,下载失败。使用 txt 扩展名保存 JSON 文件对我有用。

回答by Alexandru

I just wanted to expand on the accepted answer with support for Internet Explorer (most modern versions, anyways), and to tidy up the code using jQuery:

我只是想通过支持 Internet Explorer(大多数现代版本,无论如何)来扩展已接受的答案,并使用 jQuery 整理代码:

$(document).ready(function() {
    saveFile("Example.txt", "data:attachment/text", "Hello, world.");
});

function saveFile (name, type, data) {
    if (data !== null && navigator.msSaveBlob)
        return navigator.msSaveBlob(new Blob([data], { type: type }), name);
    var a = $("<a style='display: none;'/>");
    var url = window.URL.createObjectURL(new Blob([data], {type: type}));
    a.attr("href", url);
    a.attr("download", name);
    $("body").append(a);
    a[0].click();
    window.URL.revokeObjectURL(url);
    a.remove();
}

Here is an example Fiddle. Godspeed.

这是一个示例 Fiddle神速

回答by Kim Nyholm

Same principle as the solutions above. But I had issues with Firefox 52.0 (32 bit) where large files (>40 MBytes) are truncated at random positions. Re-scheduling the call of revokeObjectUrl() fixes this issue.

与上述解决方案的原理相同。但是我在使用 Firefox 52.0(32 位)时遇到了问题,其中大文件(> 40 MB)在随机位置被截断。重新安排 revokeObjectUrl() 的调用可修复此问题。

function saveFile(blob, filename) {
  if (window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(blob, filename);
  } else {
    const a = document.createElement('a');
    document.body.appendChild(a);
    const url = window.URL.createObjectURL(blob);
    a.href = url;
    a.download = filename;
    a.click();
    setTimeout(() => {
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);
    }, 0)
  }
}

回答by ben

Late, but since I had the same problem I add my solution:

晚了,但由于我遇到了同样的问题,我添加了我的解决方案:

function newFile(data, fileName) {
    var json = JSON.stringify(data);
    //IE11 support
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        let blob = new Blob([json], {type: "application/json"});
        window.navigator.msSaveOrOpenBlob(blob, fileName);
    } else {// other browsers
        let file = new File([json], fileName, {type: "application/json"});
        let exportUrl = URL.createObjectURL(file);
        window.location.assign(exportUrl);
        URL.revokeObjectURL(exportUrl);
    }
}

回答by Jean-Philippe

saveFileOnUserDevice = function(file){ // content: blob, name: string
        if(navigator.msSaveBlob){ // For ie and Edge
            return navigator.msSaveBlob(file.content, file.name);
        }
        else{
            let link = document.createElement('a');
            link.href = window.URL.createObjectURL(file.content);
            link.download = file.name;
            document.body.appendChild(link);
            link.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));
            link.remove();
            window.URL.revokeObjectURL(link.href);
        }
    }

回答by Sacky San

window.location.assign did not work for me. it downloads fine but downloads without an extension for a CSV file on Windows platform. The following worked for me.

window.location.assign 对我不起作用。它可以正常下载,但在 Windows 平台上下载时没有 CSV 文件的扩展名。以下对我有用。

    var blob = new Blob([csvString], { type: 'text/csv' });
    //window.location.assign(window.URL.createObjectURL(blob));
    var link = window.document.createElement('a');
    link.href = window.URL.createObjectURL(blob);
    // Construct filename dynamically and set to link.download
    link.download = link.href.split('/').pop() + '.' + extension; 
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);

回答by dabeng

This is my solution. From my point of view, you can not bypass the <a>.

这是我的解决方案。在我看来,你无法绕过<a>.

function export2json() {
  const data = {
    a: '111',
    b: '222',
    c: '333'
  };
  const a = document.createElement("a");
  a.href = URL.createObjectURL(
    new Blob([JSON.stringify(data, null, 2)], {
      type: "application/json"
    })
  );
  a.setAttribute("download", "data.json");
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}
<button onclick="export2json()">Export data to json file</button>

回答by user1032613

Working exampleof a download button, to save a cat photo from an url as "cat.jpg":

下载按钮的工作示例,将来自 url 的猫照片保存为“cat.jpg”:

HTML:

HTML:

<button onclick="downloadUrl('https://i.imgur.com/AD3MbBi.jpg', 'cat.jpg')">Download</button>

JavaScript:

JavaScript:

function downloadUrl(url, filename) {
  let xhr = new XMLHttpRequest();
  xhr.open("GET", url, true);
  xhr.responseType = "blob";
  xhr.onload = function(e) {
    if (this.status == 200) {
      const blob = this.response;
      const a = document.createElement("a");
      document.body.appendChild(a);
      const blobUrl = window.URL.createObjectURL(blob);
      a.href = blobUrl;
      a.download = filename;
      a.click();
      setTimeout(() => {
        window.URL.revokeObjectURL(blobUrl);
        document.body.removeChild(a);
      }, 0);
    }
  };
  xhr.send();
}