2013-10-11 20 views
83

Wie legen Sie den Namen einer BLOB-Datei in JavaScript fest, wenn das Herunterladen durch window.location erzwungen wird?JavaScript Blob Dateiname ohne Link

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

den obigen Code Laufen lädt eine Datei sofort ohne Aktualisierung der Seite, die wie bfefe410-8d9c-4883-86c5-d76c50a24a1d aussieht. Ich möchte stattdessen den Dateinamen als my-download.json festlegen.

Antwort

163

Der einzige Weg, mir bewusst bin, ist der von FileSaver.js verwendet Trick:

  1. einen versteckten <a>-Tag erstellen.
  2. Setzen Sie das Attribut href auf die URL des Blobs.
  3. Setzen Sie das Attribut download auf den Dateinamen.
  4. Klicken Sie auf den Tag <a>.

Hier ist ein vereinfachtes Beispiel (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); 

ich dieses Beispiel schrieb nur die Idee zu veranschaulichen, in der Produktion Code Verwendung FileSaver.js statt.

Hinweise

  • Ältere Browser den "download" Attribut nicht unterstützen, da sie Teil von HTML5 ist.
  • Einige Dateiformate werden vom Browser als unsicher angesehen und der Download schlägt fehl. Speichern von JSON-Dateien mit TXT-Erweiterung funktioniert für mich.
+0

Seltsamerweise scheint es zu versagen, wenn ich es kopiere und in CodePen einfügen. Obwohl Ihr Code scheint echt und gut http://codepen.io/ashblue/pen/jEhmH –

+0

Ihr Code-Code funktioniert für mich in Chrome. Die JSON-Datei wird im Download-Ordner von Chrome gespeichert. – kol

+2

@AshBlue Das "Download" -Attribut benötigt HTML5. Mein Code ist nur ein Beispiel, Sie können auch die FileSaver.js-Demoseite ausprobieren: http://eligrey.com/demos/FileSaver.js/ – kol

-19
 
$http.get(FILE_URL { 
          responseType: 'arraybuffer' 
          }).then(function(response) { 
          var file = new Blob([response.data], {type: fType}); 
          a.href = window.URL.createObjectURL(file); 
          a.download = fname; 
          a.click(); 
          }); 
+26

abgelehnt, weil dies im Wesentlichen die gleiche wie die angenommene Antwort ist, außer schlecht formatiert, nicht annotiert und 2 Jahre später geschrieben. –

27

Ich wollte nur mit Unterstützung für Internet Explorer (die meisten modernen Versionen, sowieso), auf die akzeptierte Antwort erweitern und auch den Code mit jQuery und Aufräumen:

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

1

Gleiches Prinzip wie die obigen Lösungen. Aber ich hatte Probleme mit Firefox 52.0 (32 Bit), wo große Dateien (> 40 MByte) an zufälligen Positionen abgeschnitten werden. Eine Neuplanung des Aufrufs von revokeObjectUrl() behebt dieses Problem.

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