Come attivare il download di un file quando si fa clic su un pulsante HTML o JavaScript


434

Questo è pazzo ma non so come farlo, e per quanto siano comuni le parole, è difficile trovare quello che mi serve sui motori di ricerca. Sto pensando che dovrebbe essere facile rispondere a questa domanda.

Voglio un semplice download di file, che farebbe lo stesso di questo:

<a href="file.doc">Download!</a>

Ma voglio usare un pulsante HTML, ad esempio uno di questi:

<input type="button" value="Download!">
<button>Download!</button>

Allo stesso modo, è possibile attivare un semplice download tramite JavaScript?

$("#fileRequest").click(function(){ /* code to download? */ });

Sicuramente non sto cercando un modo per creare un anchor che assomigli a un pulsante, utilizzare qualsiasi script back-end o pasticciare con le intestazioni del server o i tipi mime.


15
Grazie a te "come attivare un download di file in javascript" darebbe risposte molto più velocemente per qualsiasi futuro ricercatore.
Danubian Sailor,

Risposte:


278

Per il pulsante che puoi fare

<form method="get" action="file.doc">
   <button type="submit">Download!</button>
</form>

È possibile salvare il tag del modulo e aggiungere semplicemente un clic sul tag del pulsante.
Florian Leitgeb,

12
non funziona come trigger, reindirizza all'URL come tag "a".
fdrv,

7
Funziona meglio: <a href="path_to_file" download="proposed_file_name"> Download </a>
kscius

11
@kscius anche oggi l'attributo download non è supportato in IE 11 (ora è supportato in Edge) e non è supportato in Safari. Nel 2012, quando la risposta era stata inizialmente pubblicata, non era supportata in nessun browser principale.
Cfreak,

1
qual è la differenza tra avere un'ancora con lo stile del pulsante e avere una forma con un pulsante?
Andrei Epure,

444

È possibile attivare un download con l' downloadattributo HTML5 .

<a href="path_to_file" download="proposed_file_name">Download</a>

Dove:

  • path_to_fileè un percorso che si risolve in un URL sulla stessa origine . Ciò significa che la pagina e il file devono condividere lo stesso dominio, sottodominio, protocollo (HTTP vs. HTTPS) e porta (se specificato). Le eccezioni sono blob:e data:(che funzionano sempre) e file:(che non funziona mai).
  • proposed_file_nameè il nome file in cui salvare. Se è vuoto, il browser assume automaticamente il nome del file.

Documentazione: MDN , HTML standard su download , HTML standard sudownload , CanIUse


37
Non funziona con Safari e alcune versioni di IE
Mohamed Hussain,

4
L'uso di una combinazione di downloade target="_blank"sembra essere sufficiente a coprire la maggior parte dei casi d'uso. I browser che lo comprendono lo downloadtrattano come un download, altrimenti viene aperto in una nuova scheda.
MK10,

10
Come può essere applicato a un oggetto pulsante anziché solo un tag ?
storm_m2138

8
In realtà questo funziona solo per gli URL della stessa origine menzionati nei documenti MDN. Questa è un'enorme limitazione se stiamo cercando di sviluppare una soluzione generica
Akshat Gupta,

6
La domanda è esplicitamente chiedendo di usare un pulsante invece di un link
Quentin,

87

HTML:

<button type="submit" onclick="window.open('file.doc')">Download!</button>

8
La soluzione migliore e più pulita. Ma non hai bisogno di Javascript extra qui. È sufficiente la parte HTML con onclick.
Florian Leitgeb,

4
Cosa succede se desidero scaricare un file XML?
g07kore,

2
Grazie per il tuo codice Ho testato, può funzionare in IE, Chrome, Firefox.
muthukumar,

6
Se hai un file accettabile dal browser come un PDF, questo si aprirà in una nuova scheda per mostrare la finestra di download.
WindRider,

1
window.open può attivare il blocco dei popup in un browser e pertanto non è consigliabile. È possibile utilizzare window.location = 'path', anche se questo andrebbe nella posizione nella stessa finestra del browser.
Elendurwen,

68

Con jQuery:

$("#fileRequest").click(function() {
    // // hope the server sets Content-Disposition: attachment!
    window.location = 'file.doc';
});

1
Perfetto grazie. Ti capita di sapere se la maggior parte dei server imposterà la disposizione dei contenuti su "allegato" per impostazione predefinita?
brentonstrine,

5
Non c'è "più". Dipende completamente. Non fare affidamento sul fatto che sia impostato.
Matt Ball,

3
Questo problema mi ha reso balistico e questa è stata l'unica opzione che ha funzionato (ed è supportata da IE). Aggiungerò per qualsiasi n00bs come me che per impostare la disposizione del contenuto, tutto ciò che devi fare è: <? Php header ('Content-Disposition: allegato; nomefile = "nomefile.here"'); ?>
user124384

3
No jquery. Periodo.
Adam Arold,

1
Questo funziona se stai provando a scaricare un'immagine, si aprirà l'immagine nel browser
Dheeraj

34

Vecchio thread ma manca una semplice soluzione js:

let a = document.createElement('a')
a.href = item.url
a.download = item.url.split('/').pop()
document.body.appendChild(a)
a.click()
document.body.removeChild(a)

24
@NicholasKyriakides Un po 'mi ricorda questo gioiello: image.ibb.co/dtkUWJ/Selection_002.png
Stefanos Chrs,

@BryanLarsen quale versione di FF?
Stefanos Chrs,

1
@BryanLarsen Hai ragione, Firefox non lo consente senza aggiungere prima l'elemento al corpo. Grazie, aggiornando la risposta
Stefanos Chrs,

1
Esiste un modo per attivare la funzione javascript al termine del download? Sto solo cercando di mostrare un messaggio una volta avviato il download e rimuovere il messaggio una volta completato il download.
Mohit Bansal,

1
@mohitbansal (un) per fortuna no visto che è a livello di browser
Stefanos Chrs

23

Puoi farlo con "trucco" con iframe invisibile. Quando si imposta "src" su di esso, il browser reagisce come se si fa clic su un collegamento con lo stesso "href". A differenza della soluzione con modulo, consente di incorporare una logica aggiuntiva, ad esempio attivando il download dopo il timeout, quando vengono soddisfatte alcune condizioni, ecc.

È anche molto flessibile, non c'è nessun nuovo battito di ciglia finestra / scheda come quando si utilizza window.open.

HTML:

<iframe id="invisible" style="display:none;"></iframe>

Javascript:

function download() {
    var iframe = document.getElementById('invisible');
    iframe.src = "file.doc";
}

Lo fa, almeno se effettivamente apprnf l'iframe di document.body.
yxhuvud,

1
Questo non sembra funzionare in Chrome in questo momento, anche se funzionava. Mi chiedo se smette di funzionare a intermittenza in diverse versioni di Chrome.
Dobes Vandermeer,

Funziona in Chrome dalla versione 61.0.3163.100 (build ufficiale) (64 bit)
AndrewBenjamin,

Non funziona con le immagini in Firefox v57. Rende solo l'immagine nell'iframe.
Antony,

15

Versione Bootstrap

<a class="btn btn-danger" role="button" href="path_to_file"
   download="proposed_file_name">
  Download
</a>

Documentato nei documenti Bootstrap 4 e funziona anche in Bootstrap 3.


9
L'unica cosa che ha a che fare con Bootstrap sono i nomi delle classi, è solo la potenza di HTML5.
Machado,

3
La domanda è esplicitamente chiedersi come farlo con un pulsante anziché un collegamento.
Quentin,

2
se sapessi qualcosa del bootstrap, vedresti che è un pulsante.
John Lord,

11

Penso che questa sia la soluzione che stavi cercando

<button type="submit" onclick="window.location.href='file.doc'">Download!</button>

Ho un caso in cui il mio Javascript ha generato un file CSV. Poiché non è disponibile alcun URL remoto per il download, utilizzo la seguente implementazione.

downloadCSV: function(data){
    var MIME_TYPE = "text/csv";

    var blob = new Blob([data], {type: MIME_TYPE});
    window.location.href = window.URL.createObjectURL(blob);
}

su 404 -> modifica della pagina in una pagina di errore 404. stesso problema indicato nelle altre location.hrefsoluzioni.
Banana Acid,

9

Che dire:

<input type="button" value="Download Now!" onclick="window.location = 'file.doc';">

5
Questo non funziona, se il tuo file, ad esempio, è un'immagine, poiché verrebbe semplicemente aperto nel browser.
Juggernaut,

Un altro problema si verifica se il file è mancante, naviga l'intera pagina in una pagina 404
Hugheth

7

È possibile nascondere il collegamento per il download e fare clic sul pulsante.

<button onclick="document.getElementById('link').click()">Download!</button>
<a id="link" href="file.doc" download hidden></a>

Affinché ciò funzioni in Firefox, la risorsa deve trovarsi nello stesso dominio del documento. L'impostazione delle intestazioni CORS non aiuta.
Antony,

2
Non farlo mai
Wannes,

@Wannes perché no?
Starwarswii,

4

Se stai cercando una soluzione JavaScript vanilla (senza jQuery) e senza utilizzare l'attributo HTML5 puoi provare questo.

const download = document.getElementById("fileRequest");

download.addEventListener('click', request);

function request() {
    window.location = 'document.docx';
}
.dwnld-cta {
    border-radius: 15px 15px;
    width: 100px;
    line-height: 22px
}
<h1>Download File</h1>
<button id="fileRequest" class="dwnld-cta">Download</button>


1

Questo è ciò che alla fine ha funzionato per me poiché il file da scaricare è stato determinato al caricamento della pagina.

JS per aggiornare l'attributo action del modulo:

function setFormAction() {
    document.getElementById("myDownloadButtonForm").action = //some code to get the filename;
}

Chiamata a JS per aggiornare l'attributo action del modulo:

<body onLoad="setFormAction();">

Tag del modulo con il pulsante di invio:

<form method="get" id="myDownloadButtonForm" action="">
    Click to open document:  
    <button type="submit">Open Document</button>
</form>

Quanto segue NON ha funzionato:

<form method="get" id="myDownloadButtonForm" action="javascript:someFunctionToReturnFileName();">

probabilmente perché se hai il file al momento del caricamento, non puoi semplicemente eseguire il rendering dell'azione sul server usando un motore di template? perché la necessità di js code?
Andrei Epure,

1

Se non riesci a utilizzare il modulo, un altro approccio con downloadjs si adatta bene. Downloadjs usa BLOB e API file HTML 5 sotto il cofano:

{downloadjs (url, nome file)}) />

* è la sintassi jsx / reazioni, ma può essere utilizzata in HTML puro


Per evitare problemi CORS per le immagini su altri domini, inserisci crossorigin = "anonymous" nel tag img, in questo modo: <img src = "image.png" crossorigin = "anonymous" />
Jonathan Harris

0

Ovunque tra i tuoi tag <body>e </body>, inserisci un pulsante usando il codice seguente:

<button>
    <a href="file.doc" download>Click to Download!</a>
</button>

Questo sicuramente funzionerà!


1
Per Chrome è un'ottima soluzione
Hayk Aramyan,

1
Non funziona neanche in Safari: W3 Schools
Alex

2
Non funzionare nei browser MS è un grosso problema e Chrome non sarà sempre la risposta.
SudoKid,

Non puoi inserire un link all'interno di un pulsante in HTML
Quentin

0

Un altro modo di fare nel caso in cui tu abbia un URL complesso come quello file.doc?foo=bar&jon=doedi aggiungere un campo nascosto all'interno del modulo

<form method="get" action="file.doc">
  <input type="hidden" name="foo" value="bar" />
  <input type="hidden" name="john" value="doe" />
  <button type="submit">Download Now</button>
</form>

ispirato alla risposta di @Cfreak che non è completa


0

puoi aggiungere tag senza alcun testo ma con link. e quando fai clic sul pulsante come nel codice, esegui la funzione $ ("yourlinkclass"). click ().


-1

scarica l'attributo fallo

 <a class="btn btn-success btn-sm" href="/file_path/file.type" download>
     <span>download </span>&nbsp;<i class="fa fa-download"></i>
 </a>

2
Mi piace la tua risposta
George C.

2
La domanda è esplicitamente chiedersi come farlo con un pulsante anziché un collegamento.
Quentin,

-6

Se si utilizza il <a>tag, non dimenticare di utilizzare l'intero URL che porta al file, ovvero:

<a href="http://www.example.com/folder1/file.doc">Download</a>

Non penso che questo sia il problema qui. Inoltre, il percorso "assoluto" non è necessario se il collegamento si trova nello stesso percorso del file.
Rocket Hazmat,

@Rocket - hai ovviamente ragione sul percorso assoluto, tuttavia è il modo migliore per assicurarti di farlo bene. Lascerò all'OP per decidere se è stato utile -
Mark

La domanda è esplicitamente chiedersi come farlo con un pulsante anziché un collegamento.
Quentin,

l'attributo download non è presente in questa soluzione. Anche dopo aver aggiunto gli attributi di download non funzionerà per il dominio incrociato.
s sharif

-6

Per me il pulsante di annuncio invece del testo di ancoraggio funziona davvero bene.

<a href="file.doc"><button>Download!</button></a>

Potrebbe non essere ok per la maggior parte delle regole, ma sembra abbastanza buono.


5
Questo funziona solo perché il tuo browser non supporta i file .doc.
Design di Adrian,

Il tuo HTML non è valido. <a>gli elementi non possono contenere <button>elementi.
Quentin,

è sempre stato così? Questa risposta aveva due anni quando l'hai commentata.
John Lord,
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.