484

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?

3
  • I tried many answers in related questions, and this is the definitive answer.
    – Basj
    Commented Nov 22, 2016 at 11:28
  • Setting window.location.href works for me. Also window content does NOT change. I assume you used the wrong contentType?
    – Tigerware
    Commented Oct 23, 2019 at 11:56
  • If you’re trying to automate some downloads on the console real quick, instead of dealing with all this Javascript trickery, you could also go for generating a bunch of wget command strings to run on the shell. Commented May 7, 2023 at 20:16

33 Answers 33

438

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.

10
  • 5
    A webpage cannot open a new tab automatically. To force the browser to download, get the server to send the pdf file with a nonsense MIME-type, such as application/x-please-download-me Commented Sep 20, 2010 at 7:55
  • 15
    Nicely done! Solves the problem well. However, you may want to use: iframe.style.display = 'none'; as this will completely hide the iframe. Your current implementation will make the iframe invisible, but the iframe will still take up space at bottom of the page causing extra white space.
    – Akrikos
    Commented Aug 7, 2012 at 14:45
  • 4
    It "semi" works for me. I created the following simple test html: <html><body><iframe src="fileurl"></iframe></body></html> and it does get downloaded, but in the chrome console I see that the download was "canceled" and appears in red. This is part of a larger mobile web app, and the fact that it gets canceled breaks the app because it raises a general web failure. Any way around this?
    – Sagi Mann
    Commented Nov 21, 2012 at 15:51
  • 40
    Nice snippet. However, setting a nonsensical things type is a bit disturbing. To ask the browser to download a file it can render, use the following header: Content-Disposition: attachment; filename="downloaded.pdf" (you can of course customize the filename as you need).
    – rixo
    Commented Aug 28, 2013 at 10:03
  • 6
    How do I force the download without a server? So just an html page with some javascript. Commented Aug 19, 2015 at 4:51
363

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')
   // check to make sure you didn't have an unexpected failure (may need to check other things here depending on use case / backend)
  .then(resp => resp.status === 200 ? resp.blob() : Promise.reject('something went wrong'))
  .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);
    // or you know, something with better UX...
    alert('your file has downloaded!'); 
  })
  .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.

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!'); });
5
  • 12
    Your modern example here doesn't seem to me to make a great deal of sense. Why would you download something from a real HTTPS URL via fetch, create a blob from it, create a blob URL from the blob, and then use an anchor with the download attribute to download from the blob URL, when you could instead just... use an anchor with the download attribute to download from the HTTPS URL you started with?
    – Mark Amery
    Commented Jan 15, 2020 at 22:48
  • 2
    @MarkAmery that works too as other answers have indicated. That approach (AFAIK) doesn't give you feedback on when the download starts, when it completed and if it errored which is handy. I could add that to the answer for a "fire and forget" option. Also the [download] attribute doesn't allow for a POST or anything exotic either. Commented Jan 20, 2020 at 18:55
  • 5
    Your modern example is not quite right. It will "download" whatever the server returns. For ex, if you have an authentication error, it will return the login page or whatever the server returns and not the "downloaded file" itself.
    – klodoma
    Commented Aug 31, 2020 at 12:28
  • 1
    @klodoma - thanks I've updated it to account for non-200 response types Commented Jun 29, 2023 at 13:22
  • 2
    @MarkAmery , the download attribute doesn't work when the file is on a different origin. developer.mozilla.org/en-US/docs/Web/HTML/Element/a#download
    – Jean Costa
    Commented Nov 4, 2023 at 14:56
223
function downloadURI(uri, name) 
{
    var link = document.createElement("a");
    // If you don't know the name or want to use
    // the webserver default set name = ''
    link.setAttribute('download', name);
    link.href = uri;
    document.body.appendChild(link);
    link.click();
    link.remove();
}

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

11
  • 1
    download filename didnt change... tested in chrome in april 2015 Commented Apr 17, 2015 at 12:36
  • 7
    For me this would be perfect but it doesn't not work on Firefox neither. Any idea? Commented May 12, 2015 at 20:32
  • 4
    As mentioned in caniuse.com/#feat=download, this only works for same-origin links on recent Firefox and Chrome releases. So if your links points to another domain, it hardly works anywhere for now. Commented May 19, 2018 at 13:35
  • 12
    For it to work on Firefox, do document.body.appendChild(link) before the click and after the click you can do link.remove() to avoid polluting the DOM.
    – Okku
    Commented Jun 3, 2018 at 15:57
  • 2
    when URL is for pdf or image files it opens anothers browser window and display the files but never download them!!!
    – Aloti
    Commented Aug 4, 2021 at 21:01
82

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

7
  • 12
    Not supported in IE and Safari
    – MatPag
    Commented Oct 26, 2015 at 10:25
  • 10
    Chrome downloads, but Firefox just shows the picture.
    – Saran
    Commented Dec 2, 2015 at 21:01
  • 2
    +1 for providing that executable snippet though. Saved me the time to test it only to find out it won't work.
    – Doopy
    Commented Jan 26, 2018 at 22:19
  • 4
    Latest Chrome (Aug 2018) shows picture too (because of an absurd security restriction) so fail Commented Aug 13, 2018 at 17:30
  • Chrome doesn't download for mp4s
    – Nearoo
    Commented Dec 11, 2019 at 19:23
75

I recommend using the download attribute for download instead of jQuery:

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

This will download your file, without opening it.

4
  • 7
    It will only support Chrome, Firefox, Opera and IE (>= 13.0 ) Commented Jan 13, 2016 at 8:30
  • Edge >= 13, not IE. Also the Edge 13 implementations is buggy because the name of the file is ignored and instead you get a file with an id as the name.
    – David
    Commented Feb 17, 2016 at 14:59
  • 13
    In my opinion, this is the correct answer to the question. The other answers make sense if you have to support older browsers and need a workaround. Commented Apr 20, 2016 at 17:53
  • 3
    But what if we need to pass payload with the link?
    – y_159
    Commented Dec 5, 2021 at 19:29
20

This could be helpful if you are not require to navigate another page. This is base javascript function, so can be used in any platform where backend is in Javascript

window.location.assign('any url or file path')
4
  • This is probably the easiest solution if you can set the contentType yourself. I use it as: window.location.href = downloadFileUrl;
    – Tigerware
    Commented Oct 23, 2019 at 11:54
  • If admin doesn't want to show the URL to the user than? Commented Apr 24, 2020 at 15:16
  • @NarenVerma why do you want to hide the URL? The answer depends on that.
    – ed__
    Commented Aug 23, 2023 at 18:19
  • @ed__, After 3 years I got a reply. haha.... the admin doesn't want to show the URL. There is no reason for it. Commented Aug 24, 2023 at 2:26
19

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');
7
  • FYI, Someone suggested (via editing my post) to add $idown.attr('src', url); after creating the iframe for the first time. I dont' think is needed. It's already setting the 'src:url' in the creation step.
    – corbacho
    Commented Oct 14, 2012 at 21:11
  • Also to comment that finally I didn't use this solution because IE 9 didn't like dynamically-created iframes pointing to http:// when you are inside a https web. I had to used "window.location.href", a solution that has some inconveniences too
    – corbacho
    Commented Oct 14, 2012 at 21:27
  • the "if($idown)" part didn't work for me in the latest Chrome(24), but just creating an endless number of iframes did. Maybe because I wanted to download 12 things at the same time?
    – nessur
    Commented Nov 26, 2012 at 1:27
  • 6
    The if statement really should be: if( $idown && $idown.length > 0 )
    – iOnline247
    Commented Sep 5, 2013 at 14:20
  • 3
    Does not do anything in Chrome
    – jjxtra
    Commented Jul 15, 2014 at 4:38
11

Works on Chrome, Firefox and IE8 and above.

var link=document.createElement('a');
document.body.appendChild(link);
link.href=url ;
link.click();
2
  • 2
    This also works if you don't append the link to the DOM. Commented May 17, 2018 at 14:51
  • 1
    Unless headers returned from the server indicate to do otherwise, this will simply navigate to url, not download from it.
    – Mark Amery
    Commented Jan 15, 2020 at 22:56
11

I ended up using the below snippet and it works in most browsers, not tested in IE though.

let data = JSON.stringify([{email: "[email protected]", name: "test"}, {email: "[email protected]", name: "anothertest"}]);

let type = "application/json", name = "testfile.json";
downloader(data, type, name)

function downloader(data, type, name) {
	let blob = new Blob([data], {type});
	let url = window.URL.createObjectURL(blob);
	downloadURI(url, name);
	window.URL.revokeObjectURL(url);
}

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

Update

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

function downloader(data, type, name) {
    let blob = new Blob([data], {type});
    let url = window.URL.createObjectURL(blob);
    downloadURI(url, name);
    window.URL.revokeObjectURL(url);
}
3
  • What's the point of using MouseEvent here instead of always using click? And why append the link to the document before clicking it? Maybe this has advantages over the simpler approach shown in stackoverflow.com/a/23013574/1709587, but if so, they're not explained here.
    – Mark Amery
    Commented Jan 15, 2020 at 23:48
  • It's been a while I posted this answer. I can't remember if there's any reason behind those unnecessary lines of code.
    – Abk
    Commented Jan 28, 2020 at 4:45
  • If use a Data URI instead of a Blob URI, you can combine the downloader and downloadURI functions and write it in one line: const downloader = (data, mediaType, fileName) => Object.assign(document.createElement('a'), { href: `data:${mediaType}, ${encodeURIComponent(data)}`, download: fileName }).click(); Commented May 15, 2022 at 18:12
10

Simple example using an iframe

function downloadURL(url) {
    var hiddenIFrameID = 'hiddenDownloader',
        iframe = document.getElementById(hiddenIFrameID);
    if (iframe === null) {
        iframe = document.createElement('iframe');
        iframe.id = hiddenIFrameID;
        iframe.style.display = 'none';
        document.body.appendChild(iframe);
    }
    iframe.src = url;
};

Then just call the function wherever you want:

downloadURL('path/to/my/file');

2
  • 2
    Where is the download code? You're just adding an iframe
    – DevAB
    Commented Jul 22, 2021 at 2:13
  • It works with pdf and docx files not with jpg, png Commented Feb 21 at 12:04
9

Only seven years later here comes a one line jQuery solution using a form instead of an iframe or link:

$('<form></form>')
     .attr('action', filePath)
     .appendTo('body').submit().remove();

I've tested this in

  • Chrome 55
  • Firefox 50
  • Edge IE8-10
  • iOS 10 (Safari/Chrome)
  • Android Chrome

If anyone knows of any downsides with this solution I'd be very happy to hear about them.


Full demo:

<html>
<head><script src="https://code.jquery.com/jquery-1.11.3.js"></script></head>
<body>
<script>
    var filePath = window.prompt("Enter a file URL","http://jqueryui.com/resources/download/jquery-ui-1.12.1.zip");
    $('<form></form>').attr('action', filePath).appendTo('body').submit().remove();
</script>
</body>
</html>
5
  • 7
    This does not work if your filePath has a querystring since submitting a form will overwrite the querystring in the action attribute.
    – Bobort
    Commented May 4, 2017 at 20:23
  • 1
    I workarrounded this by adding an input to the form: var authInput = $("<input>").attr("type", "hidden").attr("name", "myQsKey").val('MyQsValue'); $('<form></form>') .attr('action', filePath) .append($(authInput)) .appendTo('body').submit().remove(); This is equivalent acessing: filepath?myQsKey=myValue Commented Mar 8, 2018 at 13:48
  • This also closes the websockets.
    – radu122
    Commented Sep 27, 2018 at 20:08
  • 2
    This looks like a really complicated way to set window.location to filePath. Just window.location = filePath; would do the same.
    – Ivo Smits
    Commented Nov 29, 2018 at 11:25
  • 1
    Regardless of whether there's a downside to this solution, per se, you haven't provided any upside to using this over a link. (And there is a downside: you can't use the download attribute this way to tell the browser that you want a download regardless of what headers the server returns, which you can do with an a element.)
    – Mark Amery
    Commented Jan 15, 2020 at 22:59
6

I don't know if the question is just too old, but setting window.location to a download url will work, as long as the download mime type is correct (for example a zip archive).

var download = function(downloadURL) {

   location = downloadURL;

});

download('http://example.com/archive.zip'); //correct usage
download('http://example.com/page.html'); //DON'T
1
  • Simple and works perfectly Commented Apr 13 at 4:25
6

You can simply make use of the Download attribute in HTML. Using good ol' Javascript, you can use this feature to download the file directly. The download attribute of the anchor tag should point to the link where the file to be downloaded is hosted.

Firstly, point the URL to your resource path:

var url = 'your url goes here';

Create an anchor tag, with the needed attributes as below:

var elem = document.createElement('a');
elem.href = url;
elem.download = url;
elem.id="downloadAnchor";

Append the anchor tag to the body element of the webpage.

document.body.appendChild(elem);

Now trigger the click event programmatically. Clicking on the anchor tag will trigger the download.

$('#downloadAnchor').click();

Putting it all together:

var url = 'your url goes here';
var elem = document.createElement('a');
elem.href = url;
elem.download = url;
elem.id="downloadAnchor";
document.body.appendChild(elem);
$('#downloadAnchor').click();

Additional Information: Nothing fancy in the above code, just client-side JavaScript which works from Chrome Devtools' Console, but powerful and also opens up a lot of possibilities like webpage crawling.

For e.g. the following chunk of code executed in the Devtools console will open all the links in the page in a new tab: Just goto this webpage , open devtools and run this script in the browser console and watch the power of JavaScript unfurl. (Note: The below code is purely for educational purposes only.)

Make sure you enable pop-ups for that site, else your anchor clicks will get disabled by the default pop-up blocker.

var links = document.getElementsByClassName("_3ATBKe");
for(var i=0;i<links.length;i++){
    var title = document.getElementsByClassName("_3ATBKe")[i].firstElementChild.firstElementChild.innerText.replaceAll('|','-').replaceAll(':','x');
    console.log('Opening..'+title);
    links[i].firstElementChild.click();
}

Note: This is not just limited to anchor clicks, you can download almost anything you find on your webpage. If something (image, audio, video) loads on your webpage, you can probably write a script to download it, even if the provision is not provided to you from the UI.

1
  • This worked great but I needed to use $('#downloadAnchor')[0].click(); not $('#downloadAnchor').click(); Commented Jan 29 at 20:04
6

I have created a npm package especially for this kind of cases (yes it is my package, but it is very suited for your case so I am comfortable mention it here).
You can check it out and see if you like it. It called fs-browsers and has nice and easy download method for client-side.
It goes like this:

import { downloadFile } from 'fs-browsers';
downloadFile(url-to-the-file);

1
6

In case you are looking for a descriptive TypeScript approach, have a look:

  1. Create a blob
  2. Create an URL using the blob
  3. Create a hidden element which can be clicked to download the file
  4. Make the script click the hyperlink HTML element
  5. Free memory
function download(content: string, fileName: string) {

  const 
      blob = new Blob([content], { type: /* some type */ }),
      urlForDownload = window.URL.createObjectURL(blob),
      const linkElement = document.createElement('a'); // create hyperlink HTML element

  linkElement.href = urlForDownload
  linkElement.download = fileName
  linkElement.click()

  URL.revokeObjectURL(urlForDownload) // free memory
}

Wait.. But what's a blob ?

The Blob object represents a blob, which is a file-like object of immutable, raw data; they can be read as text or binary data, or converted into a ReadableStream so its methods can be used for processing the data.

Blobs can represent data that isn't necessarily in a JavaScript-native format. The File interface is based on Blob, inheriting blob functionality and expanding it to support files on the user's system.

4

To improve Imagine Breaker 's answer, this is supported on FF & IE :

var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);

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

In other words, just use a dispatchEvent function instead of click();

2
  • How is this an improvement? It appears to simply be a more complicated way of doing the same thing.
    – Mark Amery
    Commented Jan 15, 2020 at 23:32
  • How do we make this as a post request?
    – y_159
    Commented Dec 5, 2021 at 19:51
4

Maybe just have your javascript open a page that just downloads a file, like when you drag a download link to a new tab:

Window.open("https://www.MyServer.
Org/downloads/ardiuno/WgiWho=?:8080")

With the opened window open a download page that auto closes.

1
  • 1
    This creates a popup window, which most browsers block Commented Dec 26, 2018 at 22:31
4

Most Complete and Working (Tested) Code for Downloading Data For FireFox, Chrome and IE Code is Following. Assume that Data is in texarea field, that has id='textarea_area' and filename is name of file where data will be downloaded.

function download(filename) {
    if (typeof filename==='undefined') filename = ""; // default
    value = document.getElementById('textarea_area').value;

    filetype="text/*";
    extension=filename.substring(filename.lastIndexOf("."));
    for (var i = 0; i < extToMIME.length; i++) {
        if (extToMIME[i][0].localeCompare(extension)==0) {
            filetype=extToMIME[i][1];
            break;
        }
    }


    var pom = document.createElement('a');
    pom.setAttribute('href', 'data: '+filetype+';charset=utf-8,' + '\ufeff' + encodeURIComponent(value)); // Added BOM too
    pom.setAttribute('download', filename);


    if (document.createEvent) {
        if (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) { // IE
            blobObject = new Blob(['\ufeff'+value]);
            window.navigator.msSaveBlob(blobObject, filename);
        } else { // FF, Chrome
            var event = document.createEvent('MouseEvents');
            event.initEvent('click', true, true);
            pom.dispatchEvent(event);
        }
    } else if( document.createEventObject ) { // Have No Idea
        var evObj = document.createEventObject();
        pom.fireEvent( 'onclick' , evObj );
    } else { // For Any Case
        pom.click();
    }

}

and then just call

<a href="javascript:download();">Download</a>

For Download Initiating.

Array for setting correct MIME type for download dialog CAN BE following:

// ----------------------- Extensions to MIME --------- //

        // List of mime types
        // combination of values from Windows 7 Registry and 
        // from C:\Windows\System32\inetsrv\config\applicationHost.config
        // some added, including .7z and .dat
    var extToMIME = [
        [".323", "text/h323"],
        [".3g2", "video/3gpp2"],
        [".3gp", "video/3gpp"],
        [".3gp2", "video/3gpp2"],
        [".3gpp", "video/3gpp"],
        [".7z", "application/x-7z-compressed"],
        [".aa", "audio/audible"],
        [".AAC", "audio/aac"],
        [".aaf", "application/octet-stream"],
        [".aax", "audio/vnd.audible.aax"],
        [".ac3", "audio/ac3"],
        [".aca", "application/octet-stream"],
        [".accda", "application/msaccess.addin"],
        [".accdb", "application/msaccess"],
        [".accdc", "application/msaccess.cab"],
        [".accde", "application/msaccess"],
        [".accdr", "application/msaccess.runtime"],
        [".accdt", "application/msaccess"],
        [".accdw", "application/msaccess.webapplication"],
        [".accft", "application/msaccess.ftemplate"],
        [".acx", "application/internet-property-stream"],
        [".AddIn", "text/xml"],
        [".ade", "application/msaccess"],
        [".adobebridge", "application/x-bridge-url"],
        [".adp", "application/msaccess"],
        [".ADT", "audio/vnd.dlna.adts"],
        [".ADTS", "audio/aac"],
        [".afm", "application/octet-stream"],
        [".ai", "application/postscript"],
        [".aif", "audio/x-aiff"],
        [".aifc", "audio/aiff"],
        [".aiff", "audio/aiff"],
        [".air", "application/vnd.adobe.air-application-installer-package+zip"],
        [".amc", "application/x-mpeg"],
        [".application", "application/x-ms-application"],
        [".art", "image/x-jg"],
        [".asa", "application/xml"],
        [".asax", "application/xml"],
        [".ascx", "application/xml"],
        [".asd", "application/octet-stream"],
        [".asf", "video/x-ms-asf"],
        [".ashx", "application/xml"],
        [".asi", "application/octet-stream"],
        [".asm", "text/plain"],
        [".asmx", "application/xml"],
        [".aspx", "application/xml"],
        [".asr", "video/x-ms-asf"],
        [".asx", "video/x-ms-asf"],
        [".atom", "application/atom+xml"],
        [".au", "audio/basic"],
        [".avi", "video/x-msvideo"],
        [".axs", "application/olescript"],
        [".bas", "text/plain"],
        [".bcpio", "application/x-bcpio"],
        [".bin", "application/octet-stream"],
        [".bmp", "image/bmp"],
        [".c", "text/plain"],
        [".cab", "application/octet-stream"],
        [".caf", "audio/x-caf"],
        [".calx", "application/vnd.ms-office.calx"],
        [".cat", "application/vnd.ms-pki.seccat"],
        [".cc", "text/plain"],
        [".cd", "text/plain"],
        [".cdda", "audio/aiff"],
        [".cdf", "application/x-cdf"],
        [".cer", "application/x-x509-ca-cert"],
        [".chm", "application/octet-stream"],
        [".class", "application/x-java-applet"],
        [".clp", "application/x-msclip"],
        [".cmx", "image/x-cmx"],
        [".cnf", "text/plain"],
        [".cod", "image/cis-cod"],
        [".config", "application/xml"],
        [".contact", "text/x-ms-contact"],
        [".coverage", "application/xml"],
        [".cpio", "application/x-cpio"],
        [".cpp", "text/plain"],
        [".crd", "application/x-mscardfile"],
        [".crl", "application/pkix-crl"],
        [".crt", "application/x-x509-ca-cert"],
        [".cs", "text/plain"],
        [".csdproj", "text/plain"],
        [".csh", "application/x-csh"],
        [".csproj", "text/plain"],
        [".css", "text/css"],
        [".csv", "text/csv"],
        [".cur", "application/octet-stream"],
        [".cxx", "text/plain"],
        [".dat", "application/octet-stream"],
        [".datasource", "application/xml"],
        [".dbproj", "text/plain"],
        [".dcr", "application/x-director"],
        [".def", "text/plain"],
        [".deploy", "application/octet-stream"],
        [".der", "application/x-x509-ca-cert"],
        [".dgml", "application/xml"],
        [".dib", "image/bmp"],
        [".dif", "video/x-dv"],
        [".dir", "application/x-director"],
        [".disco", "text/xml"],
        [".dll", "application/x-msdownload"],
        [".dll.config", "text/xml"],
        [".dlm", "text/dlm"],
        [".doc", "application/msword"],
        [".docm", "application/vnd.ms-word.document.macroEnabled.12"],
        [".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"],
        [".dot", "application/msword"],
        [".dotm", "application/vnd.ms-word.template.macroEnabled.12"],
        [".dotx", "application/vnd.openxmlformats-officedocument.wordprocessingml.template"],
        [".dsp", "application/octet-stream"],
        [".dsw", "text/plain"],
        [".dtd", "text/xml"],
        [".dtsConfig", "text/xml"],
        [".dv", "video/x-dv"],
        [".dvi", "application/x-dvi"],
        [".dwf", "drawing/x-dwf"],
        [".dwp", "application/octet-stream"],
        [".dxr", "application/x-director"],
        [".eml", "message/rfc822"],
        [".emz", "application/octet-stream"],
        [".eot", "application/octet-stream"],
        [".eps", "application/postscript"],
        [".etl", "application/etl"],
        [".etx", "text/x-setext"],
        [".evy", "application/envoy"],
        [".exe", "application/octet-stream"],
        [".exe.config", "text/xml"],
        [".fdf", "application/vnd.fdf"],
        [".fif", "application/fractals"],
        [".filters", "Application/xml"],
        [".fla", "application/octet-stream"],
        [".flr", "x-world/x-vrml"],
        [".flv", "video/x-flv"],
        [".fsscript", "application/fsharp-script"],
        [".fsx", "application/fsharp-script"],
        [".generictest", "application/xml"],
        [".gif", "image/gif"],
        [".group", "text/x-ms-group"],
        [".gsm", "audio/x-gsm"],
        [".gtar", "application/x-gtar"],
        [".gz", "application/x-gzip"],
        [".h", "text/plain"],
        [".hdf", "application/x-hdf"],
        [".hdml", "text/x-hdml"],
        [".hhc", "application/x-oleobject"],
        [".hhk", "application/octet-stream"],
        [".hhp", "application/octet-stream"],
        [".hlp", "application/winhlp"],
        [".hpp", "text/plain"],
        [".hqx", "application/mac-binhex40"],
        [".hta", "application/hta"],
        [".htc", "text/x-component"],
        [".htm", "text/html"],
        [".html", "text/html"],
        [".htt", "text/webviewhtml"],
        [".hxa", "application/xml"],
        [".hxc", "application/xml"],
        [".hxd", "application/octet-stream"],
        [".hxe", "application/xml"],
        [".hxf", "application/xml"],
        [".hxh", "application/octet-stream"],
        [".hxi", "application/octet-stream"],
        [".hxk", "application/xml"],
        [".hxq", "application/octet-stream"],
        [".hxr", "application/octet-stream"],
        [".hxs", "application/octet-stream"],
        [".hxt", "text/html"],
        [".hxv", "application/xml"],
        [".hxw", "application/octet-stream"],
        [".hxx", "text/plain"],
        [".i", "text/plain"],
        [".ico", "image/x-icon"],
        [".ics", "application/octet-stream"],
        [".idl", "text/plain"],
        [".ief", "image/ief"],
        [".iii", "application/x-iphone"],
        [".inc", "text/plain"],
        [".inf", "application/octet-stream"],
        [".inl", "text/plain"],
        [".ins", "application/x-internet-signup"],
        [".ipa", "application/x-itunes-ipa"],
        [".ipg", "application/x-itunes-ipg"],
        [".ipproj", "text/plain"],
        [".ipsw", "application/x-itunes-ipsw"],
        [".iqy", "text/x-ms-iqy"],
        [".isp", "application/x-internet-signup"],
        [".ite", "application/x-itunes-ite"],
        [".itlp", "application/x-itunes-itlp"],
        [".itms", "application/x-itunes-itms"],
        [".itpc", "application/x-itunes-itpc"],
        [".IVF", "video/x-ivf"],
        [".jar", "application/java-archive"],
        [".java", "application/octet-stream"],
        [".jck", "application/liquidmotion"],
        [".jcz", "application/liquidmotion"],
        [".jfif", "image/pjpeg"],
        [".jnlp", "application/x-java-jnlp-file"],
        [".jpb", "application/octet-stream"],
        [".jpe", "image/jpeg"],
        [".jpeg", "image/jpeg"],
        [".jpg", "image/jpeg"],
        [".js", "application/x-javascript"],
        [".json", "application/json"],
        [".jsx", "text/jscript"],
        [".jsxbin", "text/plain"],
        [".latex", "application/x-latex"],
        [".library-ms", "application/windows-library+xml"],
        [".lit", "application/x-ms-reader"],
        [".loadtest", "application/xml"],
        [".lpk", "application/octet-stream"],
        [".lsf", "video/x-la-asf"],
        [".lst", "text/plain"],
        [".lsx", "video/x-la-asf"],
        [".lzh", "application/octet-stream"],
        [".m13", "application/x-msmediaview"],
        [".m14", "application/x-msmediaview"],
        [".m1v", "video/mpeg"],
        [".m2t", "video/vnd.dlna.mpeg-tts"],
        [".m2ts", "video/vnd.dlna.mpeg-tts"],
        [".m2v", "video/mpeg"],
        [".m3u", "audio/x-mpegurl"],
        [".m3u8", "audio/x-mpegurl"],
        [".m4a", "audio/m4a"],
        [".m4b", "audio/m4b"],
        [".m4p", "audio/m4p"],
        [".m4r", "audio/x-m4r"],
        [".m4v", "video/x-m4v"],
        [".mac", "image/x-macpaint"],
        [".mak", "text/plain"],
        [".man", "application/x-troff-man"],
        [".manifest", "application/x-ms-manifest"],
        [".map", "text/plain"],
        [".master", "application/xml"],
        [".mda", "application/msaccess"],
        [".mdb", "application/x-msaccess"],
        [".mde", "application/msaccess"],
        [".mdp", "application/octet-stream"],
        [".me", "application/x-troff-me"],
        [".mfp", "application/x-shockwave-flash"],
        [".mht", "message/rfc822"],
        [".mhtml", "message/rfc822"],
        [".mid", "audio/mid"],
        [".midi", "audio/mid"],
        [".mix", "application/octet-stream"],
        [".mk", "text/plain"],
        [".mmf", "application/x-smaf"],
        [".mno", "text/xml"],
        [".mny", "application/x-msmoney"],
        [".mod", "video/mpeg"],
        [".mov", "video/quicktime"],
        [".movie", "video/x-sgi-movie"],
        [".mp2", "video/mpeg"],
        [".mp2v", "video/mpeg"],
        [".mp3", "audio/mpeg"],
        [".mp4", "video/mp4"],
        [".mp4v", "video/mp4"],
        [".mpa", "video/mpeg"],
        [".mpe", "video/mpeg"],
        [".mpeg", "video/mpeg"],
        [".mpf", "application/vnd.ms-mediapackage"],
        [".mpg", "video/mpeg"],
        [".mpp", "application/vnd.ms-project"],
        [".mpv2", "video/mpeg"],
        [".mqv", "video/quicktime"],
        [".ms", "application/x-troff-ms"],
        [".msi", "application/octet-stream"],
        [".mso", "application/octet-stream"],
        [".mts", "video/vnd.dlna.mpeg-tts"],
        [".mtx", "application/xml"],
        [".mvb", "application/x-msmediaview"],
        [".mvc", "application/x-miva-compiled"],
        [".mxp", "application/x-mmxp"],
        [".nc", "application/x-netcdf"],
        [".nsc", "video/x-ms-asf"],
        [".nws", "message/rfc822"],
        [".ocx", "application/octet-stream"],
        [".oda", "application/oda"],
        [".odc", "text/x-ms-odc"],
        [".odh", "text/plain"],
        [".odl", "text/plain"],
        [".odp", "application/vnd.oasis.opendocument.presentation"],
        [".ods", "application/oleobject"],
        [".odt", "application/vnd.oasis.opendocument.text"],
        [".one", "application/onenote"],
        [".onea", "application/onenote"],
        [".onepkg", "application/onenote"],
        [".onetmp", "application/onenote"],
        [".onetoc", "application/onenote"],
        [".onetoc2", "application/onenote"],
        [".orderedtest", "application/xml"],
        [".osdx", "application/opensearchdescription+xml"],
        [".p10", "application/pkcs10"],
        [".p12", "application/x-pkcs12"],
        [".p7b", "application/x-pkcs7-certificates"],
        [".p7c", "application/pkcs7-mime"],
        [".p7m", "application/pkcs7-mime"],
        [".p7r", "application/x-pkcs7-certreqresp"],
        [".p7s", "application/pkcs7-signature"],
        [".pbm", "image/x-portable-bitmap"],
        [".pcast", "application/x-podcast"],
        [".pct", "image/pict"],
        [".pcx", "application/octet-stream"],
        [".pcz", "application/octet-stream"],
        [".pdf", "application/pdf"],
        [".pfb", "application/octet-stream"],
        [".pfm", "application/octet-stream"],
        [".pfx", "application/x-pkcs12"],
        [".pgm", "image/x-portable-graymap"],
        [".pic", "image/pict"],
        [".pict", "image/pict"],
        [".pkgdef", "text/plain"],
        [".pkgundef", "text/plain"],
        [".pko", "application/vnd.ms-pki.pko"],
        [".pls", "audio/scpls"],
        [".pma", "application/x-perfmon"],
        [".pmc", "application/x-perfmon"],
        [".pml", "application/x-perfmon"],
        [".pmr", "application/x-perfmon"],
        [".pmw", "application/x-perfmon"],
        [".png", "image/png"],
        [".pnm", "image/x-portable-anymap"],
        [".pnt", "image/x-macpaint"],
        [".pntg", "image/x-macpaint"],
        [".pnz", "image/png"],
        [".pot", "application/vnd.ms-powerpoint"],
        [".potm", "application/vnd.ms-powerpoint.template.macroEnabled.12"],
        [".potx", "application/vnd.openxmlformats-officedocument.presentationml.template"],
        [".ppa", "application/vnd.ms-powerpoint"],
        [".ppam", "application/vnd.ms-powerpoint.addin.macroEnabled.12"],
        [".ppm", "image/x-portable-pixmap"],
        [".pps", "application/vnd.ms-powerpoint"],
        [".ppsm", "application/vnd.ms-powerpoint.slideshow.macroEnabled.12"],
        [".ppsx", "application/vnd.openxmlformats-officedocument.presentationml.slideshow"],
        [".ppt", "application/vnd.ms-powerpoint"],
        [".pptm", "application/vnd.ms-powerpoint.presentation.macroEnabled.12"],
        [".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"],
        [".prf", "application/pics-rules"],
        [".prm", "application/octet-stream"],
        [".prx", "application/octet-stream"],
        [".ps", "application/postscript"],
        [".psc1", "application/PowerShell"],
        [".psd", "application/octet-stream"],
        [".psess", "application/xml"],
        [".psm", "application/octet-stream"],
        [".psp", "application/octet-stream"],
        [".pub", "application/x-mspublisher"],
        [".pwz", "application/vnd.ms-powerpoint"],
        [".qht", "text/x-html-insertion"],
        [".qhtm", "text/x-html-insertion"],
        [".qt", "video/quicktime"],
        [".qti", "image/x-quicktime"],
        [".qtif", "image/x-quicktime"],
        [".qtl", "application/x-quicktimeplayer"],
        [".qxd", "application/octet-stream"],
        [".ra", "audio/x-pn-realaudio"],
        [".ram", "audio/x-pn-realaudio"],
        [".rar", "application/octet-stream"],
        [".ras", "image/x-cmu-raster"],
        [".rat", "application/rat-file"],
        [".rc", "text/plain"],
        [".rc2", "text/plain"],
        [".rct", "text/plain"],
        [".rdlc", "application/xml"],
        [".resx", "application/xml"],
        [".rf", "image/vnd.rn-realflash"],
        [".rgb", "image/x-rgb"],
        [".rgs", "text/plain"],
        [".rm", "application/vnd.rn-realmedia"],
        [".rmi", "audio/mid"],
        [".rmp", "application/vnd.rn-rn_music_package"],
        [".roff", "application/x-troff"],
        [".rpm", "audio/x-pn-realaudio-plugin"],
        [".rqy", "text/x-ms-rqy"],
        [".rtf", "application/rtf"],
        [".rtx", "text/richtext"],
        [".ruleset", "application/xml"],
        [".s", "text/plain"],
        [".safariextz", "application/x-safari-safariextz"],
        [".scd", "application/x-msschedule"],
        [".sct", "text/scriptlet"],
        [".sd2", "audio/x-sd2"],
        [".sdp", "application/sdp"],
        [".sea", "application/octet-stream"],
        [".searchConnector-ms", "application/windows-search-connector+xml"],
        [".setpay", "application/set-payment-initiation"],
        [".setreg", "application/set-registration-initiation"],
        [".settings", "application/xml"],
        [".sgimb", "application/x-sgimb"],
        [".sgml", "text/sgml"],
        [".sh", "application/x-sh"],
        [".shar", "application/x-shar"],
        [".shtml", "text/html"],
        [".sit", "application/x-stuffit"],
        [".sitemap", "application/xml"],
        [".skin", "application/xml"],
        [".sldm", "application/vnd.ms-powerpoint.slide.macroEnabled.12"],
        [".sldx", "application/vnd.openxmlformats-officedocument.presentationml.slide"],
        [".slk", "application/vnd.ms-excel"],
        [".sln", "text/plain"],
        [".slupkg-ms", "application/x-ms-license"],
        [".smd", "audio/x-smd"],
        [".smi", "application/octet-stream"],
        [".smx", "audio/x-smd"],
        [".smz", "audio/x-smd"],
        [".snd", "audio/basic"],
        [".snippet", "application/xml"],
        [".snp", "application/octet-stream"],
        [".sol", "text/plain"],
        [".sor", "text/plain"],
        [".spc", "application/x-pkcs7-certificates"],
        [".spl", "application/futuresplash"],
        [".src", "application/x-wais-source"],
        [".srf", "text/plain"],
        [".SSISDeploymentManifest", "text/xml"],
        [".ssm", "application/streamingmedia"],
        [".sst", "application/vnd.ms-pki.certstore"],
        [".stl", "application/vnd.ms-pki.stl"],
        [".sv4cpio", "application/x-sv4cpio"],
        [".sv4crc", "application/x-sv4crc"],
        [".svc", "application/xml"],
        [".swf", "application/x-shockwave-flash"],
        [".t", "application/x-troff"],
        [".tar", "application/x-tar"],
        [".tcl", "application/x-tcl"],
        [".testrunconfig", "application/xml"],
        [".testsettings", "application/xml"],
        [".tex", "application/x-tex"],
        [".texi", "application/x-texinfo"],
        [".texinfo", "application/x-texinfo"],
        [".tgz", "application/x-compressed"],
        [".thmx", "application/vnd.ms-officetheme"],
        [".thn", "application/octet-stream"],
        [".tif", "image/tiff"],
        [".tiff", "image/tiff"],
        [".tlh", "text/plain"],
        [".tli", "text/plain"],
        [".toc", "application/octet-stream"],
        [".tr", "application/x-troff"],
        [".trm", "application/x-msterminal"],
        [".trx", "application/xml"],
        [".ts", "video/vnd.dlna.mpeg-tts"],
        [".tsv", "text/tab-separated-values"],
        [".ttf", "application/octet-stream"],
        [".tts", "video/vnd.dlna.mpeg-tts"],
        [".txt", "text/plain"],
        [".u32", "application/octet-stream"],
        [".uls", "text/iuls"],
        [".user", "text/plain"],
        [".ustar", "application/x-ustar"],
        [".vb", "text/plain"],
        [".vbdproj", "text/plain"],
        [".vbk", "video/mpeg"],
        [".vbproj", "text/plain"],
        [".vbs", "text/vbscript"],
        [".vcf", "text/x-vcard"],
        [".vcproj", "Application/xml"],
        [".vcs", "text/plain"],
        [".vcxproj", "Application/xml"],
        [".vddproj", "text/plain"],
        [".vdp", "text/plain"],
        [".vdproj", "text/plain"],
        [".vdx", "application/vnd.ms-visio.viewer"],
        [".vml", "text/xml"],
        [".vscontent", "application/xml"],
        [".vsct", "text/xml"],
        [".vsd", "application/vnd.visio"],
        [".vsi", "application/ms-vsi"],
        [".vsix", "application/vsix"],
        [".vsixlangpack", "text/xml"],
        [".vsixmanifest", "text/xml"],
        [".vsmdi", "application/xml"],
        [".vspscc", "text/plain"],
        [".vss", "application/vnd.visio"],
        [".vsscc", "text/plain"],
        [".vssettings", "text/xml"],
        [".vssscc", "text/plain"],
        [".vst", "application/vnd.visio"],
        [".vstemplate", "text/xml"],
        [".vsto", "application/x-ms-vsto"],
        [".vsw", "application/vnd.visio"],
        [".vsx", "application/vnd.visio"],
        [".vtx", "application/vnd.visio"],
        [".wav", "audio/wav"],
        [".wave", "audio/wav"],
        [".wax", "audio/x-ms-wax"],
        [".wbk", "application/msword"],
        [".wbmp", "image/vnd.wap.wbmp"],
        [".wcm", "application/vnd.ms-works"],
        [".wdb", "application/vnd.ms-works"],
        [".wdp", "image/vnd.ms-photo"],
        [".webarchive", "application/x-safari-webarchive"],
        [".webtest", "application/xml"],
        [".wiq", "application/xml"],
        [".wiz", "application/msword"],
        [".wks", "application/vnd.ms-works"],
        [".WLMP", "application/wlmoviemaker"],
        [".wlpginstall", "application/x-wlpg-detect"],
        [".wlpginstall3", "application/x-wlpg3-detect"],
        [".wm", "video/x-ms-wm"],
        [".wma", "audio/x-ms-wma"],
        [".wmd", "application/x-ms-wmd"],
        [".wmf", "application/x-msmetafile"],
        [".wml", "text/vnd.wap.wml"],
        [".wmlc", "application/vnd.wap.wmlc"],
        [".wmls", "text/vnd.wap.wmlscript"],
        [".wmlsc", "application/vnd.wap.wmlscriptc"],
        [".wmp", "video/x-ms-wmp"],
        [".wmv", "video/x-ms-wmv"],
        [".wmx", "video/x-ms-wmx"],
        [".wmz", "application/x-ms-wmz"],
        [".wpl", "application/vnd.ms-wpl"],
        [".wps", "application/vnd.ms-works"],
        [".wri", "application/x-mswrite"],
        [".wrl", "x-world/x-vrml"],
        [".wrz", "x-world/x-vrml"],
        [".wsc", "text/scriptlet"],
        [".wsdl", "text/xml"],
        [".wvx", "video/x-ms-wvx"],
        [".x", "application/directx"],
        [".xaf", "x-world/x-vrml"],
        [".xaml", "application/xaml+xml"],
        [".xap", "application/x-silverlight-app"],
        [".xbap", "application/x-ms-xbap"],
        [".xbm", "image/x-xbitmap"],
        [".xdr", "text/plain"],
        [".xht", "application/xhtml+xml"],
        [".xhtml", "application/xhtml+xml"],
        [".xla", "application/vnd.ms-excel"],
        [".xlam", "application/vnd.ms-excel.addin.macroEnabled.12"],
        [".xlc", "application/vnd.ms-excel"],
        [".xld", "application/vnd.ms-excel"],
        [".xlk", "application/vnd.ms-excel"],
        [".xll", "application/vnd.ms-excel"],
        [".xlm", "application/vnd.ms-excel"],
        [".xls", "application/vnd.ms-excel"],
        [".xlsb", "application/vnd.ms-excel.sheet.binary.macroEnabled.12"],
        [".xlsm", "application/vnd.ms-excel.sheet.macroEnabled.12"],
        [".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],
        [".xlt", "application/vnd.ms-excel"],
        [".xltm", "application/vnd.ms-excel.template.macroEnabled.12"],
        [".xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template"],
        [".xlw", "application/vnd.ms-excel"],
        [".xml", "text/xml"],
        [".xmta", "application/xml"],
        [".xof", "x-world/x-vrml"],
        [".XOML", "text/plain"],
        [".xpm", "image/x-xpixmap"],
        [".xps", "application/vnd.ms-xpsdocument"],
        [".xrm-ms", "text/xml"],
        [".xsc", "application/xml"],
        [".xsd", "text/xml"],
        [".xsf", "text/xml"],
        [".xsl", "text/xml"],
        [".xslt", "text/xml"],
        [".xsn", "application/octet-stream"],
        [".xss", "application/xml"],
        [".xtp", "application/octet-stream"],
        [".xwd", "image/x-xwindowdump"],
        [".z", "application/x-compress"],
        [".zip", "application/x-zip-compressed"]
];

// ----------------------- End of Extensions to MIME --------- //
1
  • - I was trying this with pdf files. File is getting downloaded but its always corrupt. Any suggestions? Thank you Commented Dec 27, 2019 at 8:57
3

You have to do it from two sides, from the server and from the client (web app).

From the server, set the header called Content-Disposition https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition

// nodejs express
  res.set('Content-Disposition', `attachment; filename="${self.creationName}"`)

With the above header, the server will tell the browser that the response is a file and it should be downloaded and saved with given name, otherwise the browser may save the file as something like "attachments (1).zip"

Next we look at the client, we create an anchor link and automatically click it.

function downloadThroughAnchorLink(downloadUrl: string, fileName: string) {
    const a = document.createElement('a')
    a.href = downloadUrl;
    // We provided a header called Content-Disposition so we dont need to set "a.download" here
    // a.download = fileName || 'download'
    a.click()
}

That should do it.

Alternatively, you can download a file like this:

    const downloadUrl = 'https://localhost:3001/myfile.xlsx';
    const result = await fetch(downloadUrl, {
        headers: { authorization: `Bearer ${auth.authToken}` }
    })
    const file = await result.blob()
    const fileUrl = URL.createObjectURL(file)
    const filename = `Report - ${userName}.xlsx`
    downloadThroughAnchorLink(fileUrl, filename);
2

There are so many little things that can happen when trying to download a file. The inconsistency between browsers alone is a nightmare. I ended up using this great little library. https://github.com/rndme/download

Nice thing about it is that its flexible for not only urls but for client side data you want to download.

  1. text string
  2. text dataURL
  3. text blob
  4. text arrays
  5. html string
  6. html blob
  7. ajax callback
  8. binary files
2
let args = {"data":htmlData,"filename":exampleName}

To create a HTMl file and download

window.downloadHTML = function(args) {
var data, filename, link;
var csv = args.data;
if (csv == null) return;
filename = args.filename || 'report.html';
data = 'data:text/html;charset=utf-8,' + encodeURIComponent(csv);
console.log(data);
link = document.createElement('a');
link.setAttribute('href', data);
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);}

To create and download a CSV

window.downloadCSV = function(args) {
var data, filename, link;
var csv = args.data;
if (csv == null) return;
filename = args.filename || 'report.csv';
if (!csv.match(/^data:text\/csv/i)) {
    csv = 'data:text/csv;charset=utf-8,' + csv;
}
data = encodeURI(csv);
link = document.createElement('a');
link.setAttribute('href', data);
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);

}

1

for me this is working ok tested in chrome v72

function down_file(url,name){
var a = $("<a>")
    .attr("href", url)
    .attr("download", name)
    .appendTo("body");
a[0].click();
a.remove();
}

down_file('https://www.useotools.com/uploads/nulogo[1].png','logo.png')
2
  • 1
    This is just the same approach as shown in Imagine Breaker's answer years earlier, but with the added downside of requiring jQuery.
    – Mark Amery
    Commented Jan 15, 2020 at 23:37
  • we can pass some request payload in the body section with the url? It'll be like hitting the url with a POST request. How do we pass a dictionary in this case?
    – y_159
    Commented Dec 5, 2021 at 19:49
1

Only pass link of the file. It will download the file with it's original name.

function downloadFileWithLink(href) {
    var link = document.createElement("a");
    let name = (href?.split("/") || [])
    name = name[name?.length-1]
    link.setAttribute('download', name);
    link.href = href;
    document.body.appendChild(link);
    link.click();
    link.remove();
}
0

These functions are used in stacktrace.js:

/**
 * Try XHR methods in order and store XHR factory.
 *
 * @return <Function> XHR function or equivalent
 */
var createXMLHTTPObject = function() {
    var xmlhttp, XMLHttpFactories = [
        function() {
            return new XMLHttpRequest();
        }, function() {
            return new ActiveXObject('Msxml2.XMLHTTP');
        }, function() {
            return new ActiveXObject('Msxml3.XMLHTTP');
        }, function() {
            return new ActiveXObject('Microsoft.XMLHTTP');
        }
    ];
    for (var i = 0; i < XMLHttpFactories.length; i++) {
        try {
            xmlhttp = XMLHttpFactories[i]();
            // Use memoization to cache the factory
            createXMLHTTPObject = XMLHttpFactories[i];
            return xmlhttp;
        } catch (e) {
        }
    }
}

/**
 * @return the text from a given URL
 */
function ajax(url) {
    var req = createXMLHTTPObject();
    if (req) {
        try {
            req.open('GET', url, false);
            req.send(null);
            return req.responseText;
        } catch (e) {
        }
    }
    return '';
}
1
  • This... seems to just be for XHR, not file downloads? I don't see the relevance here.
    – Mark Amery
    Commented Jan 15, 2020 at 23:50
0

I suggest you use the mousedown event, which is called BEFORE the click event. That way, the browser handles the click event naturally, which avoids any code weirdness:

(function ($) {


    // with this solution, the browser handles the download link naturally (tested in chrome and firefox)
    $(document).ready(function () {

        var url = '/private/downloads/myfile123.pdf';
        $("a#someID").on('mousedown', function () {
            $(this).attr("href", url);
        });

    });
})(jQuery);
0

Excelent solution from Corbacho, I just adapted to get rid o the var

function downloadURL(url) {
    if( $('#idown').length ){
        $('#idown').attr('src',url);
    }else{
        $('<iframe>', { id:'idown', src:url }).hide().appendTo('body');
    }
}
0

Firefox and Chrome tested:

var link = document.createElement('a');
link.download = 'fileName.ext'
link.href = 'http://down.serv/file.ext';

// Because firefox not executing the .click() well
// We need to create mouse event initialization.
var clickEvent = document.createEvent("MouseEvent");
clickEvent.initEvent("click", true, true);

link.dispatchEvent(clickEvent);

This is actually the "chrome" way solution for firefox (I am not tested it on other browsers, so please leave comments about the compilability)

0

I have had good results with using a FORM tag since it works everywhere and you don't have to create temporarily files on server. The method works like this.

On the client side (page HTML) you create an invisible form like this

<form method="POST" action="/download.php" target="_blank" id="downloadForm">
    <input type="hidden" name="data" id="csv">
</form>

Then you add this Javascript code to your button:

$('#button').click(function() {
     $('#csv').val('---your data---');
     $('#downloadForm').submit();
}

The on the server-side you have the following PHP code in download.php:

<?php
header('Content-Type: text/csv');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=out.csv');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . strlen($data));

echo $_REQUEST['data'];
exit();

You can even create zip files of your data like this:

<?php

$file = tempnam("tmp", "zip");

$zip = new ZipArchive();
$zip->open($file, ZipArchive::OVERWRITE);
$zip->addFromString('test.csv', $_REQUEST['data']);
$zip->close();

header('Content-Type: application/zip');
header('Content-Length: ' . filesize($file));
header('Content-Disposition: attachment; filename="file.zip"');
readfile($file);
unlink($file); 

The best part is it does not leave any residual files on your server since everything is created and destroyed on the fly!

-1

The answer submitted by hitesh on Dec 30 '13 does in fact work. It just requires a little adjusting:

The PHP file can call itself. In other words, just create a file named saveAs.php, and put this code into it...

        <a href="saveAs.php?file_source=YourDataFile.pdf">Download pdf here</a>

    <?php
        if (isset($_GET['file_source'])) {
            $fullPath = $_GET['file_source'];
            if($fullPath) {
                $fsize = filesize($fullPath);
                $path_parts = pathinfo($fullPath);
                $ext = strtolower($path_parts["extension"]);
                switch ($ext) {
                    case "pdf":
                    header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
                    header("Content-type: application/pdf"); // add here more headers for diff. extensions
                    break;
                    default;
                    header("Content-type: application/octet-stream");
                    header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
                }
                if($fsize) {//checking if file size exist
                  header("Content-length: $fsize");
                }
                readfile($fullPath);
                exit;
            }
        }
    ?>
-1

Note: Not supported in all browsers.

I was looking for a way to download a file using jquery without having to set the file url in the href attribute from the beginning.

jQuery('<a/>', {
    id: 'downloadFile',
    href: 'http://cdn.sstatic.net/Sites/stackoverflow/img/[email protected]',
    style: 'display:hidden;',
    download: ''
}).appendTo('body');

$("#downloadFile")[0].click();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Not the answer you're looking for? Browse other questions tagged or ask your own question.