16

I want to be able to download a given file when pressing a button.The file will be provided via an API call.For now, I will have it in my local storage. So my folder is something like :

rootFolder
-JS file
-HTML file
-download file (`sample.csv`)

How can I create a download link? I have tried so far with : <a download="sample.csv"></a> I have also tried using an onclick event:

<a download="sample.csv" onclick="download()"></a>

function download|(){
   .....code that calls the `api`
}

I do not know how these 2 fit: the download API if there is one and the click event handler if you plan to do additional logic when downloading.

AmerllicA
  • 29,059
  • 15
  • 130
  • 154
Bercovici Adrian
  • 8,794
  • 17
  • 73
  • 152
  • 1
    _“For now i will have it in my local storage”_ - do you actually mean https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage, or are you just talking about the file being located in the server file system at the place where you described? – 04FS Feb 11 '19 at 08:33
  • The file is located in the server file system at the place i described. – Bercovici Adrian Feb 11 '19 at 08:34
  • 1
    Okay, so then you just need to do things correctly, and it should work … You still need to use the `href` attribute of the link to refer to the file; `download` is an extra attribute you add. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#Attributes – 04FS Feb 11 '19 at 08:37

3 Answers3

37

You can provide the link to this function to download the file :

function downloadURI(uri, name) 
{
    var link = document.createElement("a");
    link.download = name;
    link.href = uri;
    link.click();
}
saibbyweb
  • 2,864
  • 2
  • 27
  • 48
  • And if the file is in my local storage it works all the same ? – Bercovici Adrian Feb 11 '19 at 08:07
  • what exactly do you mean by local storage? aren't you using any local server ? – saibbyweb Feb 11 '19 at 08:09
  • You can simplify the function in one line as: `const downloadFile = (url, filename) => Object.assign(document.createElement('a'), { href: url, download: filename }).click();` – Adam Sassano May 15 '22 at 13:02
  • ONLY suitable where the amount of data is less than the maximum allowable URI length (~2000) [as explained by Paul Dixon's Jan 6, 2009 at 16:22](https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers/) – dank8 Oct 03 '22 at 05:21
  • He probably meant: "What if the file is a blob" – Aifos Si Prahs Oct 30 '22 at 13:41
19

since the answer from @saibbyweb does not work in all browsers as I write this, i recommend an other but similar solution, tested and working in latest (as of writing) Firefox, Chrome, Opera, Edge, Safari, mobile Safari, mobile Chrome:

function downloadUrl(url){
    window.open(url, '_self');
}

Needless to say you could also open links in new Tabs with _blank instead of _self, but you potentially startle Popup-Blockers by opening new tabs/windows with Javascript.

mondjunge
  • 1,219
  • 14
  • 24
  • is there a way to set a file name this way? – Zoidbergseasharp Mar 30 '22 at 14:05
  • @Zoid Since this directly opens an url, only the server can send approriate Headers to set a filename for the download. – mondjunge Apr 01 '22 at 10:11
  • 1
    Use the [Content-Disposition header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition) to set a file name (e.g., `Content-Disposition: attachment; filename="sample.csv"`) – Sean Apr 12 '22 at 21:59
0

You can do it via HTML <a href="/path/to/sample.csv"></a>, but if you have to do it in JS there is https://github.com/eligrey/FileSaver.js/ library.