Download fil ved hjælp af Javascript/jQuery

Jeg har et meget lignende krav, som er specificeret her.

Jeg har brug for at få brugeren's browser til at starte en download manuelt når $('a#someID').click();

Men jeg kan ikke bruge metoden window.href, da den erstatter det aktuelle sideindhold med den fil man forsøger at downloade.

I stedet ønsker jeg at åbne download i nyt vindue/tab. Hvordan er dette muligt?

Løsning

Brug en usynlig <iframe>:


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

For at tvinge browseren til at downloade en fil, som den ellers ville være i stand til at gengive (f.eks. HTML- eller tekstfiler), skal serveren indstille filens MIME Type til en meningsløs værdi, f.eks. application/x-please-download-me eller alternativt application/octet-stream, som bruges til vilkårlige binære data.

Hvis du kun ønsker at åbne den i en ny fane, er den eneste måde at gøre dette på, at brugeren skal klikke på et link med target-attributten sat til _blank.

I jQuery:

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

Når der klikkes på dette link, downloader det filen i en ny fane/et nyt vindue.

Kommentarer (21)

2019 opdatering af moderne browsere

Det er den fremgangsmåde, jeg nu vil anbefale med et par forbehold:

  • En relativt moderne browser er påkrævet.
  • Hvis filen forventes at være meget stor, bør du sandsynligvis gøre noget, der ligner den oprindelige fremgangsmåde (iframe og cookie), fordi nogle af nedenstående operationer sandsynligvis kan forbruge systemhukommelse mindst lige så stor som den fil, der downloades, og/eller andre interessante CPU-bivirkninger.
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 original jQuery/iframe/cookie baseret tilgang

Jeg har oprettet jQuery File Download plugin (Demo) (GitHub), som også kunne hjælpe i din situation. Det fungerer ret ens med en iframe, men har nogle fede funktioner, som jeg har fundet ret praktiske:

  • Meget let at opsætte med flotte visuelle elementer (jQuery UI Dialog, men ikke påkrævet), alt er også testet

  • Brugeren forlader aldrig den samme side, som de indledte en fil download fra. Denne funktion er ved at blive afgørende for moderne webapplikationer

  • successCallback- og failCallback-funktioner gør det muligt for dig at være eksplicit om, hvad brugeren ser i begge situationer

  • I forbindelse med jQuery UI kan en udvikler nemt vise en modal, der fortæller brugeren, at der er ved at blive downloadet en fil, opløse modalen, når downloadet er startet, eller endda informere brugeren på en venlig måde om, at der er opstået en fejl. Se Demo for et eksempel på dette. Håber dette hjælper nogen!

Her er en simpel use case-demo, der bruger plugin source med promises. Demosiden indeholder også mange andre, 'bedre UX' eksempler.

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

Hvis du allerede bruger jQuery, kan du udnytte det til at fremstille et mindre uddrag En jQuery-version af Andrew's svar:

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');
Kommentarer (7)