So lösen Sie einen Dateidownload aus, wenn Sie auf eine HTML-Schaltfläche oder JavaScript klicken

433

Das ist verrückt, aber ich weiß nicht, wie ich das machen soll, und weil die Wörter so häufig vorkommen, ist es schwierig, in Suchmaschinen zu finden, was ich brauche. Ich denke, das sollte leicht zu beantworten sein.

Ich möchte einen einfachen Dateidownload, der das Gleiche tun würde:

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

Ich möchte jedoch eine HTML-Schaltfläche verwenden, z. B. eine der folgenden:

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

Ist es auch möglich, einen einfachen Download über JavaScript auszulösen?

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

Ich bin definitiv nicht auf der Suche nach einer Möglichkeit, einen Anker zu erstellen, der wie eine Schaltfläche aussieht, Back-End-Skripte zu verwenden oder mit Server-Headern oder MIME-Typen herumzuspielen.

Brentonstrin
quelle
15
Dank Ihnen würde "wie man einen Dateidownload in Javascript auslöst" Antworten für jeden zukünftigen Sucher viel schneller geben.
Danubian Sailor

Antworten:

278

Für die Schaltfläche können Sie tun

<form method="get" action="file.doc">
   <button type="submit">Download!</button>
</form>
Cfreak
quelle
Sie können das Formular-Tag speichern und dem Schaltflächen-Tag einfach einen Klick hinzufügen.
Florian Leitgeb
12
funktioniert nicht als Auslöser, sondern leitet die URL einfach als 'a'-Tag weiter.
fdrv
7
Dies funktioniert besser: <a href="path_to_file" download="proposed_file_name"> Download </a>
kscius
11
@kscius Auch heute noch wird das Download-Attribut in IE 11 nicht unterstützt (es wird jetzt in Edge unterstützt) und es wird in Safari nicht unterstützt. Im Jahr 2012, als die Antwort ursprünglich veröffentlicht wurde, wurde sie in keinem größeren Browser unterstützt.
Cfreak
1
Was ist der Unterschied zwischen einem Anker mit Schaltflächenstil und einem Formular mit Schaltflächen?
Andrei Epure
443

Sie können einen Download mit dem HTML5- downloadAttribut auslösen .

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

Wo:

  • path_to_fileist ein Pfad, der in eine URL mit demselben Ursprung aufgelöst wird . Das bedeutet, dass die Seite und die Datei dieselbe Domäne, Unterdomäne, dasselbe Protokoll (HTTP vs. HTTPS) und denselben Port (falls angegeben) haben müssen. Ausnahmen sind blob:und data:(die immer funktionieren) und file:(die nie funktionieren).
  • proposed_file_nameist der Dateiname, in dem gespeichert werden soll. Wenn es leer ist, verwendet der Browser standardmäßig den Dateinamen.

Dokumentation: MDN , HTML Standard beim Herunterladen , HTML Standard beidownload , CanIUse

Joe Pigott
quelle
37
Nicht mit Safari und bestimmten IE-Versionen arbeiten
Mohamed Hussain
4
Die Verwendung einer Kombination von downloadund target="_blank"scheint ausreichend zu sein, um die meisten Anwendungsfälle abzudecken. Browser, die das verstehen, downloadbehandeln es als Download, andernfalls wird es in einem neuen Tab geöffnet.
MK10
10
Wie kann dies auf ein Schaltflächenobjekt anstatt nur auf ein Tag angewendet werden ?
Storm_M2138
8
Tatsächlich funktioniert dies nur für URLs desselben Ursprungs, wie in den MDN-Dokumenten erwähnt. Dies ist eine große Einschränkung, wenn wir eine generische Lösung entwickeln wollen
Akshat Gupta
6
Die Frage ist explizit gefragt, eine Schaltfläche anstelle eines Links zu verwenden
Quentin
86

HTML:

<button type="submit" onclick="window.open('file.doc')">Download!</button>
Sleepyup
quelle
8
Beste und sauberste Lösung. Sie benötigen hier jedoch kein zusätzliches Javascript. HTML-Teil mit dem Onclick reicht aus.
Florian Leitgeb
4
Was ist, wenn ich eine XML-Datei herunterladen möchte?
g07kore
2
Danke für deinen Code. Ich habe getestet, es kann in IE, Chrome, Firefox funktionieren.
Muthukumar
6
Wenn Sie eine vom Browser akzeptable Datei wie eine PDF-Datei haben, wird diese stattdessen in einer neuen Registerkarte geöffnet, um den Download-Dialog anzuzeigen.
WindRider
1
window.open kann in einem Browser eine Popup-Blockierung auslösen und wird daher nicht empfohlen. Sie könnten window.location = 'path' verwenden, obwohl dies zu dem Speicherort im selben Browserfenster führen würde.
Elendurwen
68

Mit jQuery:

$("#fileRequest").click(function() {
    // // hope the server sets Content-Disposition: attachment!
    window.location = 'file.doc';
});
Matt Ball
quelle
1
Perfekt danke. Wissen Sie zufällig, ob die meisten Server die Inhaltsdisposition standardmäßig auf "Anhang" setzen?
Brentonstrine
5
Es gibt keine "meisten". Es kommt ganz darauf an. Verlassen Sie sich nicht darauf, dass es eingestellt wird.
Matt Ball
3
Dieses Problem hat mich ballistisch gemacht, und dies war die einzige Option, die funktioniert hat (und vom IE unterstützt wird). Ich werde für alle n00bs wie mich hinzufügen, dass Sie zum Festlegen der Inhaltsdisposition nur Folgendes tun müssen: <? Php header ('Inhaltsdisposition: Anhang; Dateiname = "Dateiname.hier"'); ?>
user124384
3
Keine Frage. Zeitraum.
Adam Arold
1
Diese Doest-Arbeit, wenn Sie versuchen, ein Bild herunterzuladen, würde es das Bild im Browser
öffnen
34

Alter Thread, aber es fehlt eine einfache js-Lösung:

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)
Stefanos Chrs
quelle
24
@NicholasKyriakides Erinnert mich irgendwie an dieses Juwel: image.ibb.co/dtkUWJ/Selection_002.png
Stefanos Chrs
@BryanLarsen welche Version von FF?
Stefanos Chrs
1
@BryanLarsen Sie haben Recht, Firefox lässt dies nicht zu, ohne das Element zuerst dem Körper hinzuzufügen. Vielen Dank, Aktualisierung der Antwort
Stefanos Chrs
1
Gibt es eine Möglichkeit, die Javascript-Funktion nach Abschluss des Downloads auszulösen? Versuchen Sie einfach, eine Nachricht anzuzeigen, sobald der Download beginnt, und entfernen Sie die Nachricht, sobald der Download abgeschlossen ist.
Mohit Bansal
1
@mohitbansal (un) zum Glück nein, da es in der Browser-Ebene ist
Stefanos Chrs
23

Sie können es mit "Trick" mit unsichtbarem Iframe tun. Wenn Sie "src" festlegen, reagiert der Browser so, als würden Sie auf einen Link mit demselben "href" klicken. Im Gegensatz zur Lösung mit Formular können Sie zusätzliche Logik einbetten, z. B. das Aktivieren des Downloads nach einer Zeitüberschreitung, wenn einige Bedingungen erfüllt sind usw.

Es ist auch sehr leise, es gibt kein blinkendes neues Fenster / Tab wie bei der Verwendung window.open.

HTML:

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

Javascript:

function download() {
    var iframe = document.getElementById('invisible');
    iframe.src = "file.doc";
}
Donau-Seemann
quelle
Zumindest dann, wenn Sie den Iframe tatsächlich für document.body genehmigen.
Yxhuvud
1
Dies scheint derzeit in Chrome nicht zu funktionieren, obwohl es früher funktioniert hat. Ich frage mich, ob es in verschiedenen Versionen von Chrome zeitweise nicht mehr funktioniert.
Dobes Vandermeer
Funktioniert in Chrome ab Version 61.0.3163.100 (Official Build) (64-Bit)
AndrewBenjamin
Funktioniert nicht mit Bildern in Firefox v57. Das Bild wird nur im Iframe gerendert.
Antony
15

Bootstrap-Version

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

Dokumentiert in Bootstrap 4-Dokumenten und funktioniert auch in Bootstrap 3.

CFP-Unterstützung
quelle
9
Das einzige, was dies mit Bootstrap zu tun hat, sind die Klassennamen, es ist nur die Leistung von HTML5.
Machado
3
In der Frage wird explizit gefragt, wie dies mit einer Schaltfläche anstelle eines Links geschehen soll.
Quentin
2
Wenn Sie überhaupt etwas über Bootstrap wüssten, würden Sie sehen, dass es sich um eine Schaltfläche handelt.
John Lord
11

Ich denke, das ist die Lösung, nach der Sie gesucht haben

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

Ich hatte einen Fall, in dem mein Javascript eine CSV-Datei generiert hat. Da es keine Remote-URL zum Herunterladen gibt, verwende ich die folgende Implementierung.

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

    var blob = new Blob([data], {type: MIME_TYPE});
    window.location.href = window.URL.createObjectURL(blob);
}
Delconis
quelle
auf 404 -> Seite zu einer 404-Fehlerseite wechseln. das gleiche Problem wie bei den anderen location.hrefLösungen angegeben.
BananaAcid
9

Wie wäre es mit:

<input type="button" value="Download Now!" onclick="window.location = 'file.doc';">
olli
quelle
5
Dies funktioniert nicht, wenn Ihre Datei beispielsweise ein Bild ist, da sie nur im Browser geöffnet wird.
Juggernaut
Ein weiteres Problem tritt auf: Wenn die Datei fehlt, wird die gesamte Seite zu einer 404-Seite navigiert
Hugheth,
7

Sie können den Download-Link ausblenden und die Schaltfläche darauf klicken lassen.

<button onclick="document.getElementById('link').click()">Download!</button>
<a id="link" href="file.doc" download hidden></a>
Starwarswii
quelle
Damit dies in Firefox funktioniert, muss sich die Ressource in derselben Domäne wie das Dokument befinden. Das Setzen von CORS-Headern hilft nicht .
Antony
2
Tun Sie das niemals
Wannes
@ Wannes warum nicht?
Starwarswii
4

Wenn Sie nach einer Vanille-JavaScript-Lösung (kein jQuery) suchen und das HTML5-Attribut nicht verwenden möchten, können Sie dies versuchen.

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>

David Willhite
quelle
1

Dies hat schließlich für mich funktioniert, da die herunterzuladende Datei beim Laden der Seite ermittelt wurde.

JS, um das Aktionsattribut des Formulars zu aktualisieren:

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

JS aufrufen, um das Aktionsattribut des Formulars zu aktualisieren:

<body onLoad="setFormAction();">

Formular-Tag mit der Schaltfläche "Senden":

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

Folgendes hat NICHT funktioniert:

<form method="get" id="myDownloadButtonForm" action="javascript:someFunctionToReturnFileName();">
Slayernoah
quelle
Wahrscheinlich, weil Sie die Aktion nicht einfach mit einer Template-Engine auf dem Server rendern können, wenn Sie die Datei zum Ladezeitpunkt haben. warum die Notwendigkeit für js Code?
Andrei Epure
1

Wenn Sie kein Formular verwenden können, passt ein anderer Ansatz mit Downloads gut. Downloadjs verwenden die API für Blob- und HTML 5-Dateien unter der Haube:

{downloadjs (URL, Dateiname)}) />

* Es ist jsx / react-Syntax, kann aber in reinem HTML verwendet werden

Gleb Dolzikov
quelle
Um CORS-Probleme für Bilder in anderen Domänen zu vermeiden, fügen Sie crossorigin = "anonym" wie folgt in das img-Tag ein: <img src = "image.png" crossorigin = "anonym" />
Jonathan Harris
0

Fügen Sie irgendwo zwischen Ihren <body>und </body>Tags eine Schaltfläche mit dem folgenden Code ein:

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

Das wird sicher funktionieren!

Ronaldo
quelle
1
Für Chrome ist es eine großartige Lösung
Hayk Aramyan
1
Funktioniert auch nicht in Safari: W3 Schools
Alex
2
Nicht in den MS-Browsern zu arbeiten ist ein ziemlich großes Problem und Chrome wird nicht immer die Antwort sein.
SudoKid
Sie können keinen Link in eine Schaltfläche in HTML
Quentin
0

Eine andere Möglichkeit für den Fall, dass Sie eine komplexe URL haben, file.doc?foo=bar&jon=doebesteht darin, ein verstecktes Feld innerhalb des Formulars hinzuzufügen

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

inspiriert von @Cfreak Antwort, die nicht vollständig ist

Bellash
quelle
0

Sie können Tags ohne Text, aber mit Link hinzufügen. und wenn Sie auf die Schaltfläche klicken, wie Sie sie im Code haben, führen Sie einfach die Funktion $ ("yourlinkclass"). click () aus.

ThisisFish
quelle
-1

Download-Attribut mach es

 <a class="btn btn-success btn-sm" href="/file_path/file.type" download>
     <span>download </span>&nbsp;<i class="fa fa-download"></i>
 </a>
Rohallah Hatami
quelle
2
Ich mag Ihre Antwort
George C.
2
In der Frage wird explizit gefragt, wie dies mit einer Schaltfläche anstelle eines Links geschehen soll.
Quentin
-6

Wenn Sie das <a>Tag verwenden, vergessen Sie nicht, die gesamte URL zu verwenden, die zur Datei führt - dh:

<a href="http://www.example.com/folder1/file.doc">Download</a>
Kennzeichen
quelle
Ich denke nicht, dass das hier das Problem ist. Auch der "absolute" Pfad wird nicht benötigt, wenn sich der Link im selben Pfad wie die Datei befindet.
Rocket Hazmat
@Rocket - Sie haben natürlich Recht mit dem absoluten Pfad, aber es ist der beste Weg, um sicherzustellen, dass er richtig ist. Ich werde es dem OP überlassen, zu entscheiden, ob es hilfreich war -
Mark
In der Frage wird explizit gefragt, wie dies mit einer Schaltfläche anstelle eines Links geschehen soll.
Quentin
Das Download-Attribut fehlt in dieser Lösung. Auch nach dem Hinzufügen von Download-Attributen funktioniert es nicht für domänenübergreifende.
s Sharif
-6

Für mich funktioniert das Hinzufügen einer Schaltfläche anstelle eines Ankertextes sehr gut.

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

Nach den meisten Regeln ist es vielleicht nicht in Ordnung, aber es sieht ziemlich gut aus.

Brana
quelle
5
Dies funktioniert nur, weil Ihr Browser keine DOC-Dateien unterstützt.
Entwurf durch Adrian
Ihr HTML ist ungültig. <a>Elemente dürfen keine <button>Elemente enthalten .
Quentin
war es aber immer so? Diese Antwort war zwei Jahre alt, als Sie das kommentierten.
John Lord