Browser / HTML Forza il download dell'immagine da src = "data: image / jpeg; base64…"


85

Sto generando un'immagine sul lato client e la visualizzo con HTML in questo modo:

<img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgICAgM...."/>

Voglio offrire la possibilità di scaricare l'immagine generata.

Come posso rendermi conto che il browser sta aprendo un file save dialoge (o semplicemente scaricare l'immagine come chrome o firefox nella cartella di download farebbe) che consente all'utente di salvare l'immagine senza fare clic con il tasto destro e salvare come sull'immagine?

Preferirei una soluzione senza interazione con il server. Quindi sono consapevole che sarebbe possibile caricare prima l'immagine e poi avviare il download.

Molte grazie!

Risposte:


119

Sostituisci semplicemente image/jpegcon application/octet-stream. Il client non riconoscerebbe l'URL come risorsa in linea e richiederebbe una finestra di dialogo per il download.

Una semplice soluzione JavaScript sarebbe:

//var img = reference to image
var url = img.src.replace(/^data:image\/[^;]+/, 'data:application/octet-stream');
window.open(url);
// Or perhaps: location.href = url;
// Or even setting the location of an <iframe> element, 

Un altro metodo consiste nell'usare un blob:URI:

var img = document.images[0];
img.onclick = function() {
    // atob to base64_decode the data-URI
    var image_data = atob(img.src.split(',')[1]);
    // Use typed arrays to convert the binary data to a Blob
    var arraybuffer = new ArrayBuffer(image_data.length);
    var view = new Uint8Array(arraybuffer);
    for (var i=0; i<image_data.length; i++) {
        view[i] = image_data.charCodeAt(i) & 0xff;
    }
    try {
        // This is the recommended method:
        var blob = new Blob([arraybuffer], {type: 'application/octet-stream'});
    } catch (e) {
        // The BlobBuilder API has been deprecated in favour of Blob, but older
        // browsers don't know about the Blob constructor
        // IE10 also supports BlobBuilder, but since the `Blob` constructor
        //  also works, there's no need to add `MSBlobBuilder`.
        var bb = new (window.WebKitBlobBuilder || window.MozBlobBuilder);
        bb.append(arraybuffer);
        var blob = bb.getBlob('application/octet-stream'); // <-- Here's the Blob
    }

    // Use the URL object to create a temporary URL
    var url = (window.webkitURL || window.URL).createObjectURL(blob);
    location.href = url; // <-- Download!
};

Documentazione pertinente


1
per qualche ragione sembra essere rotto in Chrome 19.0 beta ma funziona su Chrome 18 e Firefox, quindi sto bene. C'è la possibilità di impostare un nome file?
— alex

Non è possibile impostare il nome del file in un URI di dati. Anche quando si utilizza una tela / Blob per esportare i dati, il nome del file non può essere impostato. Ho aggiunto un altro metodo alla mia risposta (immagino che questo funzionerà in Chrome 19).
— Rob W

2
Pensi che il primo metodo sarà deprecato perché non funziona più in Chrome 19?
— alex

1
Non riesco a trovare una fonte pertinente su di esso. Ho anche trovato questa risposta , a proposito, che suggerisce come impostare un nome predefinito in Chrome (solo ancore, l'utente deve fare clic su di esso)
— Rob W

Ho anche trovato questa soluzione - sembra essere cromato solo per ora. Grazie per il vostro sostegno!
— alex

96

puoi usare l'attributo download su un tag ...

<a href="data:image/jpeg;base64,/9j/4AAQSkZ..." download="filename.jpg"></a>

vedi di più: https://developer.mozilla.org/en/HTML/element/a#attr-download


1
Come posso utilizzare questa soluzione quando generi dinamicamente la sorgente dell'immagine? Voglio dire, ho il pulsante Download, quando l'utente fa clic su di esso, eseguo alcuni calcoli, genera un'immagine base64 e ... come posso forzare il download?
— Mikhail

In Chrome non posso impostare il nome del file usando questo metodo. Il nome del file scaricato rimane "download" qualunque cosa accada. Questo accade solo quando si utilizzano i dati: immagine ...
— cmaduro

5
So che questo è un vecchio post ma secondo l'attributo 'download' del sito web di W3Schools non è supportato da IE, Safari e Opera v. <12 w3schools.com/tags/tryit.asp?filename=tryhtml5_a_download2 infatti l'ho provato con IE e non funziona .... :(
— Mirko Lugano

6
Al momento di questo commento, l' downloadattributo non è ancora supportato Safari e IE.
— TheCarver

1
ha un limite di lunghezza base64, non è possibile scaricare immagini più grandi utilizzando questo approccio.
— Kiran Chenna

15

Credo che un img tag è necessaria come figlio di un un tag, nel seguente modo:

<a download="YourFileName.jpeg" href="data:image/jpeg;base64,iVBO...CYII=">
    <img src="data:image/jpeg;base64,iVBO...CYII="></img>
</a>

o

<a download="YourFileName.jpeg" href="/path/to/OtherFile.jpg">
    <img src="/path/to/OtherFile.jpg"></img>
</a>

Solo utilizzando l' una tag come spiegato nella # 15 non ha funzionato per me con l'ultima versione di Firefox e Chrome, ma mettere gli stessi dati di immagine sia in a.href e img.src tag funzionato per me.

Da JavaScript potrebbe essere generato in questo modo:

var data = canvas.toDataURL("image/jpeg");

var img = document.createElement('img');
img.src = data;

var a = document.createElement('a');
a.setAttribute("download", "YourFileName.jpeg");
a.setAttribute("href", data);
a.appendChild(img);

var w = open();
w.document.title = 'Export Image';
w.document.body.innerHTML = 'Left-click on the image to save it.';
w.document.body.appendChild(a);

non è che abbia bisogno di un tag img all'interno, i documenti di MSDN affermano che possono essere utilizzate solo le risorse già scaricate - dovrebbe funzionare fintanto che hai l'immagine con gli stessi dati: base64 ovunque. msdn.microsoft.com/en-us/library/cc848897.aspx - "Per motivi di sicurezza, gli URI dei dati sono limitati alle risorse scaricate. Gli URI dei dati non possono essere utilizzati per la navigazione, per lo scripting o per popolare elementi frame o iframe."
— Dimitar Christoff

5

Dai un'occhiata a FileSaver.js . Fornisce una comoda saveAsfunzione che si prende cura della maggior parte delle stranezze specifiche del browser.

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.