Daten-URL-Datei herunterladen

126

Ich spiele mit der Idee, ein vollständig JavaScript-basiertes Zip / Unzip-Dienstprogramm zu erstellen, auf das jeder über einen Browser zugreifen kann. Sie können einfach ihre Zip-Datei direkt in den Browser ziehen und so alle darin enthaltenen Dateien herunterladen. Sie können auch neue Zip-Dateien erstellen, indem Sie einzelne Dateien hineinziehen.

Ich weiß, es wäre besser, es am Server zu machen, aber dieses Projekt ist nur für ein bisschen Spaß.

Das Ziehen von Dateien in den Browser sollte einfach genug sein, wenn ich die verschiedenen verfügbaren Methoden nutze. (Google Mail-Stil)

Das Codieren / Decodieren sollte hoffentlich in Ordnung sein. Ich habe einige as3-Zip-Bibliotheken gesehen, daher bin ich mir sicher, dass ich damit einverstanden sein sollte.

Mein Problem ist das Herunterladen der Dateien am Ende.

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

Dies funktioniert gut in Firefox, aber nicht in Chrom.

Ich kann die Dateien als Bilder in Chrome einbetten <img src="data:jpg/image;ba.." />, aber die Dateien müssen nicht unbedingt Bilder sein. Sie können jedes Format haben.

Kann sich jemand eine andere Lösung oder eine Problemumgehung vorstellen?

Mikee
quelle
Die derzeitige Unterstützung ist leider eher begrenzt
Casebash

Antworten:

42

Ideen:

  • Versuchen Sie eine <a href="data:...." target="_blank">(ungetestete)

  • Verwenden Sie downloadify anstelle von Daten-URLs (würde auch für IE funktionieren)

Pekka
quelle
@jcubic danke für den Hinweis auf den toten Link. Der neue Download-Speicherort scheint github.com/dcneiner/Downloadify
Pekka
Wenn Sie Flash nicht verwenden können, aber eine serverseitige Java-Komponente ausführen , können Sie Folgendes verwenden: github.com/suprememoocow/databounce . Es verwendet ein Servlet, um die Daten vom Client zu "bouncen". Es wäre ziemlich einfach, den gleichen Trick in anderen serverseitigen Technologien wie Python, ASP.NET usw. auszuführen
Andrew Newdigate
Gibt es eine Möglichkeit, dies ohne Blitz zu tun? Daten-URL für alle Browser außer IE und eine Art ActiveX-Foo für IE? (Auf diese Weise habe ich es geschafft, Musik ohne Flash abzuspielen: HTML5-Audio für alle Browser außer IE und ActiveX für IE.)
Panzi
Downloadify erwartet einen Flash Player im Browser. Wenn der Benutzer keinen Flash-Player hat, wird die Datei nicht heruntergeladen
Jeevanandan J
186

Wenn Sie der Datei auch einen vorgeschlagenen Namen geben möchten (anstelle des Standard-Downloads), können Sie in Chrome, Firefox und einigen IE-Versionen Folgendes verwenden:

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

Das folgende Beispiel zeigt die Verwendung:

downloadURI("data:text/html,HelloWorld!", "helloWorld.txt");
owencm
quelle
6
Sie können das vereinfachen mit link.click()anstelle Ihrer eventFire-funktion ... jsfiddle.net/ARTsinn/Ezx5m
yckart
3
Schöne Lösung. aber was wird der Link danach?
Webshaker
6
Die Variable 'link' verlässt am Ende der Funktion den Gültigkeitsbereich (beachten Sie, dass wir sie nie zum dom hinzugefügt haben) und wird kurz darauf als Müll gesammelt.
Owencm
8
Dies funktioniert nur in Chrome. Wenn Sie möchten, dass es in Firefox / IE funktioniert, lesen Sie die Antwort von @MartinoDino.
TrueWill
1
Ich habe es mit download.js versucht , wie hier vorgeschlagen , und es scheint zu funktionieren. :)
Joaorodr84
53

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

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

oder:

function download(url, filename) {
fetch(url).then(function(t) {
    return t.blob().then((b)=>{
        var a = document.createElement("a");
        a.href = URL.createObjectURL(b);
        a.setAttribute("download", filename);
        a.click();
    }
    );
});
}

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

Zibri
quelle
Klicken Sie auf Ereignis auf nicht vorhandenes Element: D Kein Anhang erforderlich.
Zibri
1
Ja. Sie können einfach a.click () aufrufen, nachdem Sie das Element 'a' erstellt haben, und dann a's href festlegen.
user1709076
In der Vergangenheit funktionierte das direkte Aufrufen von a.click () nicht, aber es funktionierte mit dem Ereignis. Jetzt arbeiten beide.
Zibri
1
Dies funktioniert in den meisten modernen Browsern, aber ich möchte darauf hinweisen, dass das Anhängen an das Dokument und das anschließende Entfernen erforderlich ist, um einige ältere Browser zu unterstützen.
Owencm
3
Ihre zweite Lösung sollte immer dann verwendet werden, wenn die dataUri zu groß wird (abhängig vom Browser, aber Chrome akzeptiert meiner Erfahrung nach keine Uri mit mehreren Megabyte). Siehe auch stackoverflow.com/questions/38781968/… .
neural5torm
27

Möchten Sie meine Erfahrungen teilen und jemandem helfen, der an den Downloads festhält, die in Firefox nicht funktionieren, und die Antwort auf 2014 aktualisiert. Das folgende Snippet funktioniert sowohl in Firefox als auch in Chrome und akzeptiert einen Dateinamen:

  // 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);
Martino Dino
quelle
4
Leider funktioniert es in Safari nicht. Safari scheint das downloadAttribut nicht zu erkennen . Trotzdem danke, das ist so nah wie möglich im Moment.
Moritz Petersen
Dies führt dazu, dass das Fenster in IE 11 auf den href-Wert für mich umleitet. prevetDefault (); stoppt nicht das Verhalten in IE
b_dubb
1
Danke, auch wenn btoanicht definiert ist (zB im Node Eslinted Frontend Projekt) const btxt = new Buffer(text).toString('base64'); const uri = 'data:text/csv;charset=utf-8;base64,' + btxt + ';'
Ivan Borshchov
2
Das Löschen des Links ist sinnlos, geht in der nächsten Zeile aus dem Gültigkeitsbereich und wird durch Müll gesammelt. Es ist kein gültiges Ziel zum Löschen.
Macdja38
1
Keine Notwendigkeit für document.body.appendChild ... siehe meine Antwort stackoverflow.com/a/45905238/236062
Zibri
13

Hier ist eine reine JavaScript-Lösung, die ich in Firefox und Chrome getestet habe, aber nicht in 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;
}

Bisher gefundene browserübergreifende Lösungen:

downloadify -> Benötigt Flash

Databounce -> In IE 10 und 11 getestet und funktioniert bei mir nicht. Erfordert ein Servlet und einige Anpassungen. (Erkennt den Navigator falsch. Ich musste den IE im Kompatibilitätsmodus zum Testen einstellen, den Standardzeichensatz im Servlet, das JavaScript-Optionsobjekt mit dem richtigen Servlet-Pfad für absolute Pfade ...) Bei Nicht-IE-Browsern wird die Datei im selben Fenster geöffnet.

download.js -> http://danml.com/download.html Eine andere Bibliothek ähnlich, aber nicht getestet. Behauptet, reines JavaScript zu sein, ohne Servlet oder Flash, funktioniert aber nicht mit IE <= 9.

Jesus MC
quelle
download.js ist ziemlich gut. Habe gerade einen kurzen Check auf IE11 gemacht, es funktioniert. Vielen Dank!
Ricky Jiao
12

Es gibt verschiedene Lösungen, die jedoch von HTML5 abhängen und in einigen Browsern noch nicht vollständig implementiert wurden. Die folgenden Beispiele wurden in Chrome und Firefox getestet (funktioniert teilweise).

  1. Canvas-Beispiel mit Unterstützung für das Speichern in Dateien. Stellen Sie einfach Ihren document.location.hrefDaten-URI ein.
  2. Beispiel für einen Anker-Download . Es verwendet den <a href="your-data-uri" download="filename.txt">Dateinamen angeben.
Viacheslav Dobromyslov
quelle
3
Leinwand Beispiel führt zu 404
Karel Bílek
Das Download-Attribut funktioniert für mich für eine PDF-Daten-URL in Chrome und Mobile Safari.
Bbsimonbb
7

Diese Funktion kombiniert die Antworten von @owencm und @ Chazt3n und ermöglicht das Herunterladen von Text aus IE11, Firefox und Chrome. (Entschuldigung, ich habe keinen Zugriff auf Safari oder Opera, aber bitte fügen Sie einen Kommentar hinzu, wenn Sie es versuchen und es funktioniert.)

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');
Kevinarpe
quelle
1

Für alle, die Probleme im IE haben:

Bitte stimmen Sie der Antwort von Yetti hier zu: Speichern Sie die Leinwand lokal im 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");
Chazt3n
quelle
0

Ihr Problem läuft im Wesentlichen darauf hinaus, dass "nicht alle Browser dies unterstützen".

Sie könnten eine Problemumgehung versuchen und die entpackten Dateien von einem Flash-Objekt bereitstellen, aber dann würden Sie die reine JS-Reinheit verlieren (ich bin mir sowieso nicht sicher, ob Sie derzeit Dateien ohne eine Art Flash-Problemumgehung in den Browser ziehen können) - Ist das vielleicht eine HTML5-Funktion?)

Piskvor verließ das Gebäude
quelle