Forza il browser a scaricare i file di immagine al clic


100

Ho bisogno del browser per scaricare i file di immagine proprio come fa quando faccio clic su un foglio Excel.

C'è un modo per farlo utilizzando solo la programmazione lato client?

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script type="text/javascript" src="Scripts/jquery-1.10.2.js">
        $(document).ready(function () {
            $("*").click(function () {
                $("p").hide();
            });
        });
        </script>
    </head>

    <script type="text/javascript">
        document.onclick = function (e) {
            e = e || window.event;
            var element = e.target || e.srcElement;
            if (element.innerHTML == "Image") {
                //someFunction(element.href);
                var name = element.nameProp;
                var address = element.href;
                saveImageAs1(element.nameProp, element.href);
                return false; // Prevent default action and stop event propagation
            }
            else
                return true;
        };

        function saveImageAs1(name, adress) {
            if (confirm('you wanna save this image?')) {
                window.win = open(adress);
                //response.redirect("~/testpage.html");
                setTimeout('win.document.execCommand("SaveAs")', 100);
                setTimeout('win.close()', 500);
            }
        }
    </script>

    <body>
        <form id="form1" runat="server">
            <div>
                <p>
                    <a href="http://localhost:55298/SaveImage/demo/Sample2.xlsx" target="_blank">Excel</a><br />
                    <a href="http://localhost:55298/SaveImage/demo/abc.jpg" id="abc">Image</a>
                </p>
            </div>
        </form>
    </body>
</html>

Come dovrebbe funzionare in caso di download di un foglio Excel (cosa fanno i browser)?


7
L' downloadattributo.
Šime Vidas

6
Il modo migliore per garantire il download di un file è impostare la disposizione del contenuto sul lato server, la maggior parte delle soluzioni lato client non sono così affidabili.
adeneo


V'è una domanda simile, che è già una risposta per voi: stackoverflow.com/a/6799284/1948211
dschu

Karl-Andre Gagnon: Per favore, fallo correttamente. [Non avevo taggato HTML 5 perché non voglio usarlo] e senza toccare il server
Amit

Risposte:


172

Utilizzando HTML5 puoi aggiungere l'attributo "download" ai tuoi link.

<a href="https://stackoverflow.com/path/to/image.png" download>

I browser compatibili chiederanno quindi di scaricare l'immagine con lo stesso nome di file (in questo esempio image.png).

Se specifichi un valore per questo attributo, diventerà il nuovo nome del file:

<a href="https://stackoverflow.com/path/to/image.png" download="AwesomeImage.png">

AGGIORNAMENTO: A partire dalla primavera 2018 questo non è più possibile per i cross-origin hrefs . Quindi, se vuoi creare <a href="https://i.imgur.com/IskAzqA.jpg" download>su un dominio diverso da imgur.com, non funzionerà come previsto. Annuncio di ritiro e rimozione di Chrome


Richard Parnaby-King: Utilizzando l'attributo HTML 5 può essere fatto, ma devo farlo SENZA usare HTML5 o qualsiasi strumento LATO SERVER (se è possibile farlo) Grazie per gli aiutanti :)
Amit

2
Non ancora completamente supportato in tutti i browser, ma è una buona soluzione se non ti interessa IE o Safari. caniuse.com/#feat=download
stacigh

Grazie, per una soluzione HTML5. Come consentire ancora il "Salva con nome" che mi consente di inserire un nome file prima di salvare?
teleman

Non riesco a controllare dove scaricare questo file? Si scarica solo per scaricare direttamente la cartella. Voglio che utilizzi il percorso locale del file html.
Arjun Chiddarwar

1
@ArjunChiddarwar No, questo apre vulnerabilità di sicurezza (immagina che qualcuno salvi un file dannoso direttamente nella tua cartella di Windows). Il percorso di download si basa sulle impostazioni del browser, ad esempio, per impostazione predefinita, Chrome verrà scaricato nella cartella dei download.
Richard Parnaby-King

96

Sono riuscito a farlo funzionare anche in Chrome e Firefox aggiungendo un collegamento al documento.

var link = document.createElement('a');
link.href = 'images.jpg';
link.download = 'Download.jpg';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);

2
Questa è in realtà una soluzione molto carina per le app Web in cui Javascript è ovunque. Funziona solo in Google Chrome (nella mia configurazione di prova), però.
Pavel

Qualche idea su un modo per testare la compatibilità? Mi piacerebbe usare questa tecnica ma devo supportare anche altri browser, quindi dovrei offrire un'alternativa (come aprire il PDF in una nuova finestra o un link per il download) quando questo non è supportato. Qualcuno ha avuto fortuna con quello?
alexrussell

13
Ottima soluzione, grazie! Nota che se lo ometti document.body.appendChild(link)non funzionerà in Firefox. È anche utile rimuovere l'elemento creato con document.body.removeChild(link);afterlink.click()
akn

8
soluzione migliore. Per evitare la spazzatura nell'uso DOMsetTimeout( function () { link.parentNode.removeChild( link ); },10 );
Mephiztopheles

1
Grazie avrebbe dovuto essere la risposta selezionata poiché la domanda chiedeva come farlo in JAVASCRIPT.
codehelp4

33

Leeroy e Richard Parnaby-King:

AGGIORNAMENTO: A partire dalla primavera 2018 questo non è più possibile per gli href cross-origin. Quindi, se vuoi creare su un dominio diverso da imgur.com, non funzionerà come previsto. Annuncio di ritiro e rimozione di Chrome

function forceDownload(url, fileName){
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "blob";
    xhr.onload = function(){
        var urlCreator = window.URL || window.webkitURL;
        var imageUrl = urlCreator.createObjectURL(this.response);
        var tag = document.createElement('a');
        tag.href = imageUrl;
        tag.download = fileName;
        document.body.appendChild(tag);
        tag.click();
        document.body.removeChild(tag);
    }
    xhr.send();
}

2
l'immagine viene scaricata ma non si apre perché viene indicato "L'immagine è danneggiata"
picacode

19

Aggiornamento primavera 2018

<a href="/path/to/image.jpg" download="FileName.jpg">

Sebbene sia ancora supportato, a partire da febbraio 2018 chrome ha disabilitato questa funzione per il download cross-origin, il che significa che funzionerà solo se il file si trova sullo stesso nome di dominio.

Ho trovato una soluzione alternativa per il download di immagini interdominio dopo il nuovo aggiornamento di Chrome che ha disabilitato il download interdominio. È possibile modificarlo in una funzione adatta alle proprie esigenze. Potresti essere in grado di ottenere il tipo mime dell'immagine (jpeg, png, gif, ecc.) Con qualche ricerca in più se necessario. Potrebbe esserci un modo per fare qualcosa di simile a questo anche con i video. Spero che questo aiuti qualcuno!

Leeroy e Richard Parnaby-King:

AGGIORNAMENTO: A partire dalla primavera 2018 questo non è più possibile per gli href cross-origin. Quindi, se vuoi creare su un dominio diverso da imgur.com, non funzionerà come previsto. Annuncio di ritiro e rimozione di Chrome

var image = new Image();
image.crossOrigin = "anonymous";
image.src = "https://is3-ssl.mzstatic.com/image/thumb/Music62/v4/4b/f6/a2/4bf6a267-5a59-be4f-6947-d803849c6a7d/source/200x200bb.jpg";
// get file name - you might need to modify this if your image url doesn't contain a file extension otherwise you can set the file name manually
var fileName = image.src.split(/(\\|\/)/g).pop();
image.onload = function () {
    var canvas = document.createElement('canvas');
    canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size
    canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size
    canvas.getContext('2d').drawImage(this, 0, 0);
    var blob;
    // ... get as Data URI
    if (image.src.indexOf(".jpg") > -1) {
    blob = canvas.toDataURL("image/jpeg");
    } else if (image.src.indexOf(".png") > -1) {
    blob = canvas.toDataURL("image/png");
    } else if (image.src.indexOf(".gif") > -1) {
    blob = canvas.toDataURL("image/gif");
    } else {
    blob = canvas.toDataURL("image/png");
    }
    $("body").html("<b>Click image to download.</b><br><a download='" + fileName + "' href='" + blob + "'><img src='" + blob + "'/></a>");
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


Sembra che questo codice decodifichi l'immagine in un buffer di pixel nella memoria del browser, quindi la ricodifichi come jpeg / png / gif quindi la incapsuli in un data-uri che viene quindi, si spera, archiviato localmente. Se è così, significa che tutti i metadati dal file immagine sono persi. Anche la ricodifica JPEG perderà un po 'di qualità e avrà un rapporto qualità / numero di byte peggiore. Comunque, buono a sapersi. Grazie per la condivisione.
Stéphane Gourichon

14

Un approccio più moderno che utilizza Promise e async / await:

toDataURL(url) {
    return fetch(url).then((response) => {
            return response.blob();
        }).then(blob => {
            return URL.createObjectURL(blob);
        });
}

poi

async download() {
        const a = document.createElement("a");
        a.href = await toDataURL("https://cdn1.iconfinder.com/data/icons/ninja-things-1/1772/ninja-simple-512.png");
        a.download = "myImage.png";
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
}

Trova la documentazione qui: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch


13
var pom = document.createElement('a');
pom.setAttribute('href', 'data:application/octet-stream,' + encodeURIComponent(text));
pom.setAttribute('download', filename);
pom.style.display = 'none';
document.body.appendChild(pom);
pom.click();
document.body.removeChild(pom);     

5
il browser Safari non supporta l'attributo di download
Pranav Labhe

11

Questa è una soluzione generale al tuo problema. Ma c'è una parte molto importante che l'estensione del file deve corrispondere alla tua codifica. E, naturalmente, quel parametro di contenuto della funzione downlowadImage dovrebbe essere una stringa codificata in base64 della tua immagine.

const clearUrl = url => url.replace(/^data:image\/\w+;base64,/, '');

const downloadImage = (name, content, type) => {
  var link = document.createElement('a');
  link.style = 'position: fixed; left -10000px;';
  link.href = `data:application/octet-stream;base64,${encodeURIComponent(content)}`;
  link.download = /\.\w+/.test(name) ? name : `${name}.${type}`;

  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

['png', 'jpg', 'gif'].forEach(type => {
  var download = document.querySelector(`#${type}`);
  download.addEventListener('click', function() {
    var img = document.querySelector('#img');

    downloadImage('myImage', clearUrl(img.src), type);
  });
});
a gif image: <image id="img" src="data:image/gif;base64,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" />


<button id="png">Download PNG</button>
<button id="jpg">Download JPG</button>
<button id="gif">Download GIF</button>


3
Aggiungi una breve spiegazione alla tua risposta, in modo da renderla pertinente per la persona che l'ha richiesta
ETÀ

1
link.href = 'data: application / octet-stream,' + encodeURIComponent (address) questo corrompe il file e quindi non può essere aperto, posso suggerire perché è così
OM The Eternity

Sì, questa risposta merita di essere la migliore! La parte mancante per me era la cosa "cleanUrl", che generava dati non corretti e danneggiava il file.
Iulian Pinzaru il

3

Nel 2020 utilizzo Blob per creare una copia locale dell'immagine, che il browser scaricherà come file. Puoi provarlo su questo sito .

inserisci qui la descrizione dell'immagine

(function(global) {
  const next = () => document.querySelector('.search-pagination__button-text').click();
  const uuid = () => Math.random().toString(36).substring(7);
  const toBlob = (src) => new Promise((res) => {
    const img = document.createElement('img');
    const c = document.createElement("canvas");
    const ctx = c.getContext("2d");
    img.onload = ({target}) => {
      c.width = target.naturalWidth;
      c.height = target.naturalHeight;
      ctx.drawImage(target, 0, 0);
      c.toBlob((b) => res(b), "image/jpeg", 0.75);
    };
    img.crossOrigin = "";
    img.src = src;
  });
  const save = (blob, name = 'image.png') => {
    const a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.target = '_blank';
    a.download = name;
    a.click();
  };
  global.download = () => document.querySelectorAll('.search-content__gallery-results figure > img[src]').forEach(async ({src}) => save(await toBlob(src), `${uuid()}.png`));
  global.next = () => next();
})(window);

Sembra che questo codice decodifichi l'immagine in un buffer di pixel (tela) nella memoria del browser, quindi la ricodifichi come jpeg / png / gif quindi la incapsuli in un data-uri che viene quindi, si spera, archiviato localmente. Se è così, significa che tutti i metadati dal file immagine sono persi. Anche la ricodifica JPEG perderà un po 'di qualità e avrà un rapporto qualità / numero di byte peggiore. Comunque, buono a sapersi. Grazie per la condivisione.
Stéphane Gourichon

2

Prova questo:

<a class="button" href="http://www.glamquotes.com/wp-content/uploads/2011/11/smile.jpg" download="smile.jpg">Download image</a>

0
<html>
<head>
<script type="text/javascript">
function prepHref(linkElement) {
    var myDiv = document.getElementById('Div_contain_image');
    var myImage = myDiv.children[0];
    linkElement.href = myImage.src;
}
</script>
</head>
<body>
<div id="Div_contain_image"><img src="YourImage.jpg" alt='MyImage'></div>
<a href="#" onclick="prepHref(this)" download>Click here to download image</a>
</body>
</html>

0

Puoi scaricare direttamente questo file utilizzando il tag di ancoraggio senza molto codice.
Copia lo snippet e incollalo nel tuo editor di testo e provalo ...!

<html>
<head>
</head>
<body>
   <div>
     <img src="https://upload.wikimedia.org/wikipedia/commons/1/1f/SMirC-thumbsup.svg" width="200" height="200">
      <a href="#" download="https://upload.wikimedia.org/wikipedia/commons/1/1f/SMirC-thumbsup.svg"> Download Image </a>
   </div>
</body>
</html>


2
aggiungi ulteriori dettagli, ad esempio dove può essere utilizzato questo codice.
Maciej S.

-2

Che ne dici di usare la funzione .click () e il tag?

(Versione compressa)

<a id="downloadtag" href="examplefolder/testfile.txt" hidden download></a>

<button onclick="document.getElementById('downloadtag').click()">Download</button>

Ora puoi attivarlo con js. Inoltre non apre, come altri esempi, file di immagini e di testo!

(versione funzione js)

function download(){
document.getElementById('downloadtag').click();
}
<!-- HTML -->
<button onclick="download()">Download</button>
<a id="downloadtag" href="coolimages/awsome.png" hidden download></a>


-5

l'ho trovato

<a href="link/to/My_Image_File.jpeg" download>Download Image File</a>

Non ha funzionato per me. Non sono sicuro del perché.

Ho scoperto che puoi includere un ?download=trueparametro alla fine del tuo collegamento per forzare un download. Penso di aver notato questa tecnica utilizzata da Google Drive.

Nel tuo link, includi ?download=truealla fine del tuo href.

Puoi anche usare questa tecnica per impostare il nome del file allo stesso tempo.

Nel tuo link, includi ?download=true&filename=My_Image_File.jpegalla fine del tuo href.


2
? download = true viene passato a Google Drive per dire al loro server di inviare l'intestazione corretta per scaricare l'immagine. Non è qualcosa che funzionerebbe in qualsiasi altro ambiente a meno che non sia stato appositamente impostato in questo modo.
muncherelli

-15

Non è necessario scrivere js per farlo, basta usare:

<a href="path_to/image.jpg" alt="something">Download image</a>

E il browser stesso scaricherà automaticamente l'immagine.

Se per qualche motivo non funziona aggiungi l'attributo download. Con questo attributo puoi impostare un nome per il file scaricabile:

<a href="path_to/image.jpg" download="myImage">Download image</a>

Un collegamento all'immagine aprirà solo l'immagine nella stessa finestra, a meno che il browser non sia configurato in modo diverso. L' downloadattributo non è supportato in tutti i browser.
Design di Adrian il
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.