Scarica il file url dei dati


126

Sto giocando con l'idea di creare un'utilità zip / unzip completamente basata su JavaScript a cui chiunque possa accedere da un browser. Possono semplicemente trascinare la zip direttamente nel browser e gli permetterà di scaricare tutti i file all'interno. Possono anche creare nuovi file zip trascinando i singoli file in.

So che sarebbe meglio farlo sul lato server, ma questo progetto è solo per un po 'di divertimento.

Trascinare i file nel browser dovrebbe essere abbastanza semplice se traggo vantaggio dai vari metodi disponibili. (Stile Gmail)

Si spera che la codifica / decodifica vada bene. Ho visto alcune librerie zip as3 quindi sono sicuro che dovrei andare bene con quello.

Il mio problema è il download dei file alla fine.

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

funziona bene con Firefox ma non con Chrome.

Posso incorporare i file come immagini bene in Chrome usando <img src="data:jpg/image;ba.." />, ma i file non saranno necessariamente immagini. Potrebbero essere di qualsiasi formato.

Qualcuno può pensare a un'altra soluzione o una sorta di soluzione alternativa?


Purtroppo, l' attuale supporto è piuttosto limitato
Casebash

Risposte:


42

idee:

  • Prova un <a href="data:...." target="_blank">(Non testato)

  • Usa downloadify invece degli URL dei dati (funzionerebbe anche per IE)


@jcubic grazie per aver segnalato il link morto. Il nuovo percorso di download sembra essere github.com/dcneiner/Downloadify
Pekka

Se non è possibile utilizzare Flash ma si esegue un componente lato server Java, è possibile utilizzare questo: github.com/suprememoocow/databounce . Utilizza un servlet per "rimbalzare" i dati dal client. Sarebbe abbastanza facile eseguire lo stesso trucco in altre tecnologie lato server, come Python, ASP.NET ecc.
Andrew Newdigate,

C'è un modo per farlo senza flash? URL dei dati per tutti i browser tranne IE e una sorta di pippo ActiveX per IE? (In questo modo sono riuscito a riprodurre musica senza flash: audio HTML5 per tutti i browser tranne IE e ActiveX per IE.)
Panzi,

Downloadify prevede Flash Player nel browser. Se l'utente non ha Flash Player, il file non verrà scaricato
Jeevanandan J

186

Se vuoi anche dare un nome suggerito al file (invece del "download" predefinito) puoi usare quanto segue in Chrome, Firefox e alcune versioni di IE:

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

E il seguente esempio mostra il suo utilizzo:

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

6
Puoi semplificarlo con link.click()invece della tua funzione eventFire... jsfiddle.net/ARTsinn/Ezx5m
yckart

3
Bella soluzione. ma cosa diventa il link dopo?
webshaker,

6
La variabile 'link' esce dall'ambito alla fine della funzione (si noti che non l'abbiamo mai aggiunto al dom), quindi verranno raccolti subito dopo.
Owencm,

8
Funziona solo con Chrome. Se vuoi che funzioni in Firefox / IE, guarda la risposta di @MartinoDino.
TrueWill,

1
Ho provato con download.js , come suggerito qui e sembra funzionare. :)
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");

o:

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


fare clic sull'evento sull'elemento inesistente: D nessuna necessità di appendchild.
Zibri,

1
sì. puoi semplicemente chiamare a.click () dopo aver creato l'elemento 'a', e quindi impostare a's href.
user1709076

in passato chiamare a.click () direttamente non funzionava ma funzionava con l'evento. Ora funzionano entrambi.
Zibri

1
Funziona con la maggior parte dei browser moderni, ma noterei che è necessario aggiungere il documento e rimuoverlo per supportare alcuni browser meno recenti.
owencm

3
La tua seconda soluzione dovrebbe essere utilizzata ogni volta che dataUri diventa troppo grande (dipende dal browser, ma Chrome non accetta Uri di più megabyte nella mia esperienza). Vedi anche stackoverflow.com/questions/38781968/… .
neural5torm

27

Vuoi condividere la mia esperienza e aiutare qualcuno bloccato sui download che non funzionano in Firefox e la risposta aggiornata al 2014. Lo snippet di seguito funzionerà sia in Firefox che in Chrome e accetterà un nome file:

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

4
Sfortunatamente, non funziona in Safari. Safari non sembra riconoscere l' downloadattributo. Grazie comunque, questo è il più vicino possibile al momento.
Moritz Petersen,

questo sta causando il reindirizzamento della finestra sul valore href per me in IE 11. prevetDefault (); non interrompe il comportamento in IE
b_dubb

1
Grazie, anche se btoanon definito (ad es. Nel progetto di frontend abbattuto nodo) const btxt = new Buffer(text).toString('base64'); const uri = 'data:text/csv;charset=utf-8;base64,' + btxt + ';'
Ivan Borshchov

2
l'eliminazione del collegamento non ha senso, va al di fuori dell'ambito nella riga successiva e sarà spazzatura raccolta, non è una destinazione valida per l'eliminazione.
macdja38,

1
Non c'è bisogno di document.body.appendChild ... vedi la mia risposta stackoverflow.com/a/45905238/236062
Zibri

13

Ecco una soluzione JavaScript pura che ho testato lavorando in Firefox e Chrome ma non 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;
}

Le soluzioni cross-browser finora trovate:

downloadify -> Richiede Flash

databounce -> Testato in IE 10 e 11 e non funziona per me. Richiede un servlet e alcune personalizzazioni. (Rileva erroneamente il navigatore. Ho dovuto impostare IE in modalità compatibilità per testare, set di caratteri predefinito nel servlet, oggetto opzioni JavaScript con percorso servlet corretto per percorsi assoluti ...) Per i browser non IE, apre il file nella stessa finestra.

download.js -> http://danml.com/download.html Un'altra libreria simile ma non testata. Afferma di essere puro JavaScript, non richiede servlet né Flash, ma non funziona su IE <= 9.


download.js è abbastanza buono. Ho appena fatto un rapido controllo su IE11, funziona. Molte grazie!
Ricky Jiao,

12

Esistono diverse soluzioni, ma dipendono da HTML5 e non sono ancora state implementate completamente in alcuni browser. Gli esempi seguenti sono stati testati in Chrome e Firefox (in parte funziona).

  1. Esempio di tela con supporto per salvataggio su file. Basta impostare document.location.hrefl'URI dei dati.
  2. Esempio di download dell'ancora . Usa <a href="your-data-uri" download="filename.txt">per specificare il nome del file.

3
l'esempio di tela porta al 404
Karel Bílek,

L'attributo download funziona per me, per un URL di dati pdf in Chrome e Safari mobile.
bbsimonbb,

7

Combinando le risposte di @owencm e @ Chazt3n, questa funzione consentirà il download di testo da IE11, Firefox e Chrome. (Mi dispiace, non ho accesso a Safari o Opera, ma per favore aggiungi un commento se provi e funziona.)

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

1

Per chiunque abbia problemi con IE:

Per favore, vota la risposta qui di Yetti: salvare la tela localmente in 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");

0

Il problema si riduce essenzialmente a "non tutti i browser lo supporteranno".

Potresti provare una soluzione alternativa e servire i file decompressi da un oggetto Flash, ma poi perdi la purezza solo JS (comunque, non sono sicuro se al momento puoi "trascinare i file nel browser" senza una sorta di soluzione Flash - è forse una funzionalità HTML5?)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.