Datei herunterladen mit Javascript/jQuery

Ich habe eine sehr ähnliche Anforderung hier angegeben.

Ich brauche, um die user's Browser einen Download manuell starten, wenn $('a#someID').click();

Aber ich kann die Methode window.href nicht verwenden, da sie den aktuellen Seiteninhalt durch die Datei ersetzt, die heruntergeladen werden soll.

Stattdessen möchte ich den Download in einem neuen Fenster/Tab öffnen. Wie ist das möglich?

Lösung

Verwenden Sie einen unsichtbaren <iframe>:


<script>
function Download(url) {
    document.getElementById('my_iframe').src = url;
};
</script>

Um den Browser zu zwingen, eine Datei herunterzuladen, die er andernfalls wiedergeben könnte (z. B. HTML- oder Textdateien), muss der Server den MIME-Typ der Datei auf einen unsinnigen Wert setzen, wie z. B. "application/x-please-download-me" oder alternativ "application/octet-stream", der für beliebige Binärdaten verwendet wird.

Wenn Sie den Link nur in einer neuen Registerkarte öffnen wollen, besteht die einzige Möglichkeit darin, dass der Benutzer auf einen Link klickt, dessen Attribut target auf _blank gesetzt ist.

In jQuery:

$('a#someID').attr({target: '_blank', 
                    href  : 'http://localhost/directory/file.pdf'});

Immer wenn dieser Link angeklickt wird, wird die Datei in einem neuen Tab/Fenster heruntergeladen.

Kommentare (21)

Update für moderne Browser 2019

Dies ist der Ansatz, den ich jetzt mit einigen Vorbehalten empfehlen würde:

  • Ein relativ moderner Browser ist erforderlich
  • Wenn zu erwarten ist, dass die Datei sehr groß ist, sollten Sie wahrscheinlich etwas Ähnliches wie den ursprünglichen Ansatz (iframe und Cookie) verwenden, da einige der unten aufgeführten Operationen wahrscheinlich Systemspeicher verbrauchen, der mindestens so groß ist wie die heruntergeladene Datei, und/oder andere interessante CPU-Nebeneffekte.
fetch('https://jsonplaceholder.typicode.com/todos/1')
  .then(resp => resp.blob())
  .then(blob => {
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.style.display = 'none';
    a.href = url;
    // the filename you want
    a.download = 'todo-1.json';
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
    alert('your file has downloaded!'); // or you know, something with better UX...
  })
  .catch(() => alert('oh no!'));

2012 ursprünglicher jQuery/iframe/cookie-basierter Ansatz

Ich habe das jQuery File Download Plugin (Demo) (GitHub) erstellt, das auch in Ihrer Situation helfen könnte. Es funktioniert ziemlich ähnlich mit einem iframe, hat aber einige coole Funktionen, die ich ziemlich praktisch gefunden habe:

  • Sehr einfach einzurichten, mit schöner Optik (jQuery UI Dialog, aber nicht erforderlich), alles ist auch getestet

  • Der Benutzer verlässt nie dieselbe Seite, von der aus er einen Dateidownload gestartet hat. Diese Funktion ist für moderne Webanwendungen immer wichtiger

  • Mit den Funktionen successCallback und failCallback können Sie genau festlegen, was der Benutzer in der jeweiligen Situation sieht

  • In Verbindung mit jQuery UI kann ein Entwickler auf einfache Weise ein Modal anzeigen, das dem Benutzer mitteilt, dass ein Dateidownload stattfindet, das Modal auflösen, nachdem der Download begonnen hat, oder den Benutzer sogar auf freundliche Weise darüber informieren, dass ein Fehler aufgetreten ist. In der Demo finden Sie ein Beispiel hierfür. Hoffentlich hilft das jemandem!

Hier ist ein einfaches Beispiel für einen Anwendungsfall, der das Plugin source mit Versprechen verwendet. Die Demo-Seite enthält auch viele andere, 'bessere UX' Beispiele.

$.fileDownload('some/file.pdf')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });
Kommentare (10)

Wenn Sie bereits jQuery verwenden, können Sie es nutzen, um ein kleineres Snippet zu erstellen Eine jQuery-Version von Andrew's Antwort:

var $idown;  // Keep it outside of the function, so it's initialized once.
downloadURL : function(url) {
  if ($idown) {
    $idown.attr('src',url);
  } else {
    $idown = $('<iframe>', { id:'idown', src:url }).hide().appendTo('body');
  }
},
//... How to use it:
downloadURL('http://whatever.com/file.pdf');
Kommentare (7)