371 Stimmen

HTML5/JavaScript verwenden, um eine Datei zu erzeugen und zu speichern

Ich habe in letzter Zeit mit WebGL herumgespielt und einen Collada-Reader zum Laufen gebracht. Das Problem ist, dass es ziemlich langsam ist (Collada ist ein sehr ausführliches Format), also werde ich anfangen, Dateien in ein einfacheres Format zu konvertieren (wahrscheinlich JSON). Ich habe bereits den Code, um die Datei in JavaScript zu parsen, also kann ich ihn auch als meinen Exporter verwenden! Das Problem ist das Speichern.

Jetzt weiß ich, dass ich die Datei analysieren, das Ergebnis an den Server senden und den Browser veranlassen kann, die Datei vom Server als Download zurückzufordern. Aber in Wirklichkeit hat der Server nichts mit diesem speziellen Prozess zu tun, warum sollte er also involviert werden? Ich habe den Inhalt der gewünschten Datei bereits im Speicher. Gibt es eine Möglichkeit, dem Benutzer einen Download mit reinem JavaScript zu präsentieren? (Ich bezweifle es, aber ich könnte genauso gut fragen...)

Und um das klarzustellen: Ich versuche nicht, ohne Wissen des Benutzers auf das Dateisystem zuzugreifen! Der Benutzer gibt eine Datei an (wahrscheinlich per Drag & Drop), das Skript wandelt die Datei im Speicher um, und der Benutzer wird aufgefordert, das Ergebnis herunterzuladen. All dies sollten "sichere" Aktivitäten sein, soweit der Browser betroffen ist.

[EDIT]: Ich habe es nicht im Voraus erwähnt, also sind die Poster, die mit "Flash" geantwortet haben, berechtigt, aber ein Teil dessen, was ich tue, ist ein Versuch, hervorzuheben, was mit reinem HTML5 gemacht werden kann... also ist Flash in meinem Fall ausgeschlossen. (Obwohl es eine vollkommen gültige Antwort für jeden ist, der eine "echte" Webanwendung macht.) Da dies der Fall ist, sieht es so aus, als hätte ich kein Glück, es sei denn, ich möchte den Server einbeziehen. Trotzdem vielen Dank!

335voto

Matěj Pokorný Punkte 15409

Einfache Lösung für HTML5-fähige Browser...

function download(filename, text) {
    var pom = document.createElement('a');
    pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
    pom.setAttribute('download', filename);

    if (document.createEvent) {
        var event = document.createEvent('MouseEvents');
        event.initEvent('click', true, true);
        pom.dispatchEvent(event);
    }
    else {
        pom.click();
    }
}

Verwendung

download('test.txt', 'Hello world!');

274voto

Nøk Punkte 2754

OK, die Erstellung einer data:URI ist für mich auf jeden Fall hilfreich, danke an Matthew und Dennkster, die mich auf diese Möglichkeit hingewiesen haben! Hier ist im Grunde, wie ich es tun:

1) den gesamten Inhalt in eine Zeichenkette namens "content" packen (z.B. indem man ihn dort anfangs erstellt oder indem man innerHTML des Tags einer bereits erstellten Seite liest).

2) Erstellen Sie den Daten-URI:

uriContent = "data:application/octet-stream," + encodeURIComponent(content);

Es gibt Längenbeschränkungen je nach Browsertyp usw., aber z.B. Firefox 3.6.12 funktioniert bis mindestens 256k. Kodierung in Base64 statt mit encodeURIComponent könnte die Dinge effizienter machen, aber für mich war das ok.

3) Öffnen Sie ein neues Fenster und leiten Sie es zu dieser URI um, die zum Herunterladen der mit JavaScript erstellten Seite auffordert:

newWindow = window.open(uriContent, 'neuesDokument');

Das war's.

84voto

panzi Punkte 7334

HTML5 definiert eine window.saveAs(blob, filename) Methode. Sie wird zur Zeit von keinem Browser unterstützt. Aber es gibt eine Kompatibilitätsbibliothek namens FileSaver.js die diese Funktion den meisten modernen Browsern (einschließlich Internet Explorer 10+) hinzufügt. Internet Explorer 10 unterstützt eine navigator.msSaveBlob(blob, filename) Methode ( MSDN ), die in FileSaver.js für die Unterstützung des Internet Explorer verwendet wird.

Ich schrieb eine Blog-Eintrag mit weiteren Einzelheiten zu diesem Problem.

64voto

bcmpinc Punkte 2942

Speichern von großen Dateien

Lange Daten-URIs können in Browsern zu Leistungsproblemen führen. Eine andere Möglichkeit, clientseitig generierte Dateien zu speichern, besteht darin, ihren Inhalt in ein Blob- (oder Datei-) Objekt zu packen und einen Download-Link mit URL.createObjectURL(blob) . Dies gibt eine URL zurück, die zum Abrufen des Inhalts des Blobs verwendet werden kann. Der Blob wird innerhalb des Browsers gespeichert, bis entweder URL.revokeObjectURL() für die URL aufgerufen wird oder das Dokument, das sie erstellt hat, geschlossen wird. Die meisten Webbrowser haben Unterstützung für Objekt-URLs Opera Mini ist das einzige Programm, das sie nicht unterstützt.

Erzwingen eines Downloads

Handelt es sich bei den Daten um Text oder ein Bild, kann der Browser die Datei öffnen, anstatt sie auf der Festplatte zu speichern. Um zu bewirken, dass die Datei beim Anklicken des Links heruntergeladen wird, können Sie die Option download Attribut. Allerdings verfügen nicht alle Webbrowser über Unterstützung für das Download-Attribut . Eine weitere Möglichkeit ist die Verwendung von application/octet-stream als Mime-Type der Datei, aber das führt dazu, dass die Datei als binärer Blob dargestellt wird, was besonders benutzerunfreundlich ist, wenn Sie keinen Dateinamen angeben oder angeben können. Siehe auch ' Erzwingen des Öffnens des Popup-Fensters "Speichern unter..." Öffnen bei Textlink Klick für pdf in HTML '.

Angeben eines Dateinamens

Wenn der Blob mit dem Dateikonstruktor erstellt wird, können Sie auch einen Dateinamen angeben, aber nur wenige Webbrowser (einschließlich Chrome und Firefox) haben Unterstützung für den File-Konstruktor . Der Dateiname kann auch als Argument für den Befehl download Attribut, aber dies unterliegt einer Vielzahl von Sicherheitsüberlegungen . Internet Explorer 10 und 11 bietet eine eigene Methode, msSaveBlob , um einen Dateinamen anzugeben.

Beispiel-Code

var file;
var data = [];
data.push("This is a test\n");
data.push("Of creating a file\n");
data.push("In a browser\n");
var properties = {type: 'text/plain'}; // Specify the file's mime-type.
try {
  // Specify the filename using the File constructor, but ...
  file = new File(data, "file.txt", properties);
} catch (e) {
  // ... fall back to the Blob constructor if that isn't supported.
  file = new Blob(data, properties);
}
var url = URL.createObjectURL(file);
document.getElementById('link').href = url;

<a id="link" target="_blank" download="file.txt">Download</a>

42voto

Yassir Ennazk Punkte 6253
function download(content, filename, contentType)
{
    if(!contentType) contentType = 'application/octet-stream';
        var a = document.createElement('a');
        var blob = new Blob([content], {'type':contentType});
        a.href = window.URL.createObjectURL(blob);
        a.download = filename;
        a.click();
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X