JavaScript blob filename without link

后端 未结 8 1978
一生所求
一生所求 2020-11-22 02:43

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

function newFile(data) {
    var json = J         


        
相关标签:
8条回答
  • 2020-11-22 02:51

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

    1. Create a hidden <a> tag.
    2. Set its href attribute to the blob's URL.
    3. Set its download attribute to the filename.
    4. Click on the <a> tag.

    Here is a simplified example (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.

    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.
    0 讨论(0)
  • 2020-11-22 02:54

    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:

    $(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.

    0 讨论(0)
  • 2020-11-22 02:58

    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.

    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)
      }
    }
    

    jsfiddle example

    0 讨论(0)
  • 2020-11-22 02:59

    This is my solution. From my point of view, you can not bypass the <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>

    0 讨论(0)
  • 2020-11-22 03:01

    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.

        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);
    
    0 讨论(0)
  • 2020-11-22 03:03

    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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题