Download File Using Javascript/jQuery

Download File Using Javascript/jQuery

I have a very similar requirement specified here.
I need to have the user’s browser start a download manually when $(‘a#someID’).click();
But I cannot use the window.href method, since it replaces the current page contents with the file you’re trying to download.
Instead I want to open the download in new window/tab. How is this possible?

Solutions/Answers:

Solution 1:

Use an invisible <iframe>:

<iframe id="my_iframe" style="display:none;"></iframe>
<script>
function Download(url) {
    document.getElementById('my_iframe').src = url;
};
</script>

To force the browser to download a file it would otherwise be capable of rendering (such as HTML or text files), you need the server to set the file’s MIME Type to a nonsensical value, such as application/x-please-download-me or alternatively application/octet-stream, which is used for arbitrary binary data.

If you only want to open it in a new tab, the only way to do this is for the user to a click on a link with its target attribute set to _blank.

In jQuery:

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

Whenever that link is clicked, it will download the file in a new tab/window.

Solution 2:

2019 modern browsers update

This is the approach I’d now recommend with a few caveats:

  • A relatively modern browser is required
  • If the file is expected to be very large you should likely do something similar to the original approach (iframe and cookie) because some of the below operations could likely consume system memory at least as large as the file being downloaded and/or other interesting CPU side effects.
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 based approach

I have created the jQuery File Download plugin (Demo) (GitHub) which could also help with your situation. It works pretty similarly with an iframe but has some cool features that I have found quite handy:

  • Very easy to setup with nice visuals (jQuery UI Dialog, but not required), everything is tested too

  • User never leaves the same page they initiated a file download from. This feature is becoming crucial for modern web applications

  • successCallback and failCallback functions allow for you to be explicit about what the user sees in either situation

  • In conjunction with jQuery UI a developer can easily show a modal telling the user that a file download is occurring, disband the modal after the download starts or even inform the user in a friendly manner that an error has occurred. See the Demo for an example of this. Hope this helps someone!

Here is a simple use case demo using the plugin source with promises. The demo page includes many other, ‘better UX’ examples as well.

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

Solution 3:

function downloadURI(uri, name) 
{
    var link = document.createElement("a");
    link.download = name;
    link.href = uri;
    link.click();
}

Check if your target browser(s) will run the above snippet smoothly:
http://caniuse.com/#feat=download

Solution 4:

I’m surprised not a lot of people know about the download attribute for a elements. Please help spread the word about it! You can have a hidden html link, and fake a click on it. If the html link has the download attribute it downloads the file, not views it, no matter what. Here’s the code. It will download a cat picture if it can find it.

document.getElementById('download').click();
<a href="https://docs.google.com/uc?id=0B0jH18Lft7ypSmRjdWg1c082Y2M" download id="download" hidden></a>

Note:
This is not supported on all browsers: http://www.w3schools.com/tags/att_a_download.asp

Solution 5:

I recommend using html5 for download instead of jQuery:

<a href="your_link" download> file_name </a>

This will download your file, without opening it.

Solution 6:

If you are already using jQuery, you could take adventage of it to produce a smaller snippet
A jQuery version of Andrew’s answer:

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