77

How do I initialize an automatic download of a file in Internet Explorer?

For example, in the download page, I want the download link to appear and a message: "If you download doesn't start automatically .... etc". The download should begin shortly after the page loads.

In Firefox this is easy, you just need to include a meta tag in the header, <meta http-equiv="Refresh" content="n;url"> where n is the number of seconds and url is the download URL. This does not work in Internet Explorer. How do I make this work in Internet Explorer browsers?

Liam Marshall
  • 1,353
  • 1
  • 12
  • 21
Pop Catalin
  • 61,751
  • 23
  • 87
  • 115

19 Answers19

112

SourceForge uses an <iframe> element with the src="" attribute pointing to the file to download.

<iframe width="1" height="1" frameborder="0" src="[File location]"></iframe>

(Side effect: no redirect, no JavaScript, original URL remains unchanged.)

Nathan
  • 8,093
  • 8
  • 50
  • 76
devio
  • 36,858
  • 7
  • 80
  • 143
  • 1
    Could somebody explain how that should work? I don't see delay for 'n' seconds... Thank you in advance. – Budda Aug 10 '10 at 20:08
  • 1
    This is also how audible.com does it apparently. – 3on Jun 30 '13 at 22:41
  • 9
    Ooh that is clever. You could make it `display:none`, too. Also, @Budda, some simple Javascript (Oh, no, Javascript?!?!) can add that HTML in after n seconds: HTML: `` Javascript: `function startDownload () { document.getElementById("download").src="[File Location]"; } setTimeout (startDownload, n * 1000);` – Cosine Sep 02 '13 at 00:41
  • 3
    I like the idea of using this, but it will have issues with certain file types. For example if you wish to provide a download link for a PDF or image (or any content that a browser can display), the browser would just try and display it silently in the hidden iframe. – Nathan Hornby Dec 04 '14 at 14:41
  • 7
    @NathanHornby, use `Content-Disposition: attachment; filename=manual.pdf` header on server side and everything will be ok. – zealotous Jan 14 '15 at 13:39
  • How to apply in IE 11, I really no idea on it can anyone share this to me? – Shi Jie Tio Jun 19 '17 at 07:37
  • IE: pointing the iframe to a src of https://stackoverflow.com/questions/24529910/zip-file-corrupted-when-downloaded-by-header (Cendak) solved this for me. – Teson Jun 29 '17 at 07:45
  • @zealotous Where on the server do you put `Content-Disposition: attachment; filename=manual.pdf header on server side`? – johny why Apr 28 '20 at 22:25
  • @johnywhy, you place in the header of the server response. So in pseudocode - `myResponse.setHeader('Content-Disposition','attachment; filename=manual.pdf'); send(myResponse);` – Chris - Jr Dec 01 '21 at 21:44
  • I tested with a pdf. Works correctly in Firefox, but Chrome does auto-download only if the file src url is relative. – Shahriar Nov 27 '22 at 12:23
54

I hate when sites complicate download so much and use hacks instead of a good old link.

Dead simple version:

<a href="file.zip">Start automatic download!</a>

It works! In every browser!


If you want to download a file that is usually displayed inline (such as an image) then HTML5 has a download attribute that forces download of the file. It also allows you to override filename (although there is a better way to do it):

<a href="report-generator.php" download="result.xls">Download</a>

Version with a "thanks" page:

If you want to display "thanks" after download, then use:

<a href="file.zip" 
   onclick="if (event.button==0) 
     setTimeout(function(){document.body.innerHTML='thanks!'},500)">
 Start automatic download!
</a>

Function in that setTimeout might be more advanced and e.g. download full page via AJAX (but don't navigate away from the page — don't touch window.location or activate other links).

The point is that link to download is real, can be copied, dragged, intercepted by download accelerators, gets :visited color, doesn't re-download if page is left open after browser restart, etc.

That's what I use for ImageOptim

Community
  • 1
  • 1
Kornel
  • 97,764
  • 37
  • 219
  • 309
  • 9
    I like the simplicity of your answer. – David Robbins May 23 '09 at 10:05
  • 3
    @DavidRobbins and i like the simplicity of your comment. :D – Vishwanath Dalvi Aug 31 '12 at 11:03
  • 1
    One word of caution. At least in my Chrome 21, the attempt to follow @href gets cancelled if the script from setTimeout tries to move to another page. So this really only works when you can show the thank you page inline. – Kohsuke Kawaguchi Oct 27 '12 at 17:32
  • 2
    I totally agree with using a good old link, but there is a problem with this: clients. Sometimes they want what they want no matter what you try and tell them. They've seen it on other sites, and that's what they want on their site. – raydowe Jan 29 '13 at 15:44
  • @raydowe if you make link work well, then the client won't know. Unless you have clients that view page source and make nonsensical complaints… – Kornel Jan 29 '13 at 15:45
  • 1
    @porneL I don't understand. I thought you were suggesting just using a link to the file INSTEAD of the automatic download after X seconds. – raydowe Jan 29 '13 at 15:49
  • @raydowe yes, but you can display post-download screen that looks the same as if it was implemented using the messy meta/iframe hack — load the 'thank you' page using AJAX from onclick handler. So if client's requirement is to have such page, you can use the link and still fulfill the requirement. – Kornel Jan 29 '13 at 18:15
  • The problem is currently safari, notice user wants to automatically start the download and the only way to do that with a link is to snag the element and invoke .click(). safari doesn't support click(). – Cheruvian Nov 11 '14 at 00:07
  • @Cheruvian think what action user takes before you "automatically" start the download. I'll bet that action is a click that goes to your "automatic" page. So move the download one step earlier! – Kornel Nov 11 '14 at 23:55
  • True but the issue is when you need to generate download content based on something. The current solution is 1 click for generating content and 1 click to download which can be pretty dirty – Cheruvian Nov 12 '14 at 00:39
  • Often times you need to do additional work before the download actually starts--like submitting various parameters from JS to an API so that you can prepare the file for downloading. You can't really do that if it's just an href that the user is clicking which links directly to the file content. – Bogdan Varlamov Jan 08 '15 at 19:21
  • @BogdanVarlamov: You could include the data in the URL (dynamically modify `href` if necessary) and have that URL redirect to actual file, e.g. ``. You can even change `href` from `onclick` handler and return `true`, so you can update it the instant user clicks. – Kornel Jan 09 '15 at 20:01
  • @porneL: Then one is sending potentially sensitive data in an insecure manner (via URL) instead of being able to send it in the body over HTTPS. – Bogdan Varlamov Jan 23 '15 at 01:50
  • @BogdanVarlamov HTTPS is a tunnel hiding all of HTTP protocol, including URLs, so there's no difference. And if filename contains sensitive information, maybe don't put that in the filename anyway? (it'll leak later when saved to disk) – Kornel Jan 23 '15 at 12:19
  • There are some issues specifically related to URLs which are not typically encountered for body params. Check out http://stackoverflow.com/questions/323200/is-an-https-query-string-secure and http://blog.httpwatch.com/2009/02/20/how-secure-are-query-strings-over-https/ for reasons – Bogdan Varlamov Feb 03 '15 at 20:13
  • @BogdanVarlamov 1. GET via click vs GET via javascript/iframe hack is still GET (and issues like cross-site referrer leak don't apply to download links you create). 2. sensitive information should go to a cookie with `secure` flag, and then you won't need to worry about hiding potentially-insecure URL hacks with wonky JS hacks. – Kornel Feb 04 '15 at 12:09
  • @porneL, Nobody forces you to use a GET method in JS. You can (and should) use a POST/PUT to submit the sensitive parameters in JS in the BODY (see my first comments)... with a url-click you are limited only to the GET the browser sends. – Bogdan Varlamov Feb 09 '15 at 23:01
  • @porneL, I think what I imagine is a POST/PUT that submits sensitive info which returns a URL based on that criteria which you sent, that the JS client then redirects to for executing the file download. You can avoid this by sticking the sensitive info into the URL as params, sure, but that has security problems as I pointed out. Are you saying that if you had a form submit the params, you could have the server redirect to the right file based on the params? – Bogdan Varlamov Feb 10 '15 at 21:16
  • @BogdanVarlamov POST can send the file to download directly, so there's never need to perform any redirect or put any parameters in any URL at any point, e.g. see http://imageoptim.com/mozjpeg – Kornel Feb 10 '15 at 23:10
  • Why is `Content-Disposition` better than `download` attribute for setting file name? – Robo Robok Mar 19 '18 at 16:02
  • I really like the `href= download=` usage: I have only ever seen `download` used as an attribute without the optional value. – JDQ Jul 13 '21 at 20:28
24

I recently solved it by placing the following script on the page.

setTimeout(function () { window.location = 'my download url'; }, 5000)

I agree that a meta-refresh would be nicer but if it doesn't work what do you do...

TheSoftwareJedi
  • 34,421
  • 21
  • 109
  • 151
ullmark
  • 2,469
  • 1
  • 19
  • 28
22

I had a similar issue and none of the above solutions worked for me. Here's my try (requires jquery):

$(function() {
  $('a[data-auto-download]').each(function(){
    var $this = $(this);
    setTimeout(function() {
      window.location = $this.attr('href');
    }, 2000);
  });
});

Usage: Just add an attribute called data-auto-download to the link pointing to the download in question:

<p>The download should start shortly. If it doesn't, click
<a data-auto-download href="/your/file/url">here</a>.</p>

It should work in all cases.

kikito
  • 51,734
  • 32
  • 149
  • 189
  • 1
    I like that. Nice and clean and you can add it to any link you want. I love finding cool new uses for the `data-*` attribute! – daGUY Oct 29 '12 at 16:48
8

A simple bit of jQuery solved this problem for me.

$(function() {
   $(window).bind('load', function() {
      $("div.downloadProject").delay(1500).append('<iframe width="0" height="0" frameborder="0" src="[YOUR FILE SRC]"></iframe>'); 
   });
});

In my HTML, I simply have

<div class="downloadProject"></div>

All this does is wait a second and a half, then append the div with the iframe referring to the file that you want to download. When the iframe is updated onto the page, your browser downloads the file. Simple as that. :D

CameronK
  • 89
  • 1
  • 3
6

I used this, seems working and is just simple JS, no framework:

Your file should start downloading in a few seconds. 
If downloading doesn't start automatically
<a id="downloadLink" href="[link to your file]">click here to get your file</a>.

<script> 
    var downloadTimeout = setTimeout(function () {
        window.location = document.getElementById('downloadLink').href;
    }, 2000);
</script>

NOTE: this starts the timeout in the moment the page is loaded.

John Weisz
  • 30,137
  • 13
  • 89
  • 132
Tyler
  • 349
  • 4
  • 11
  • Regarding your flag, that would be something to raise on our [meta](http://meta.stackoverflow.com) site. I believe this has come up before, however (there are quite a few similar complaints, but I can't find one directly matching this) – Tim Post Oct 04 '12 at 03:45
6

Works on Chrome, firefox and IE8 and above:

var link = document.createElement('a');
document.body.appendChild(link);
link.href = url;
link.click();
John Weisz
  • 30,137
  • 13
  • 89
  • 132
EL missaoui habib
  • 1,075
  • 1
  • 14
  • 24
5

This is what I'm using in some sites (requires jQuery).:

$(document).ready(function() {
    var downloadUrl = "your_file_url";
    setTimeout("window.location.assign('" + downloadUrl + "');", 1000);
});

The file is downloaded automatically after 1 second.

Rabi
  • 2,593
  • 1
  • 23
  • 26
3

I checked and found, it will work on button click via writing onclick event to Anchor tag or Input button

onclick='javascript:setTimeout(window.location=[File location], 1000);'
Josh Darnell
  • 11,304
  • 9
  • 38
  • 66
Vandana
  • 161
  • 7
3

Back to the roots, i use this:

<meta http-equiv="refresh" content="0; url=YOURFILEURL"/>

Maybe not WC3 conform but works perfect on all browsers, no HTML5/JQUERY/Javascript.

Greetings Tom :)

JulienD
  • 7,102
  • 9
  • 50
  • 84
Tom
  • 151
  • 10
3

I hope this will works all the browsers. You can also set the auto download timing.

<html>
<head>
<title>Start Auto Download file</title>
<script src="http://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
$(function() {
$('a[data-auto-download]').each(function(){
var $this = $(this);
setTimeout(function() {
window.location = $this.attr('href');
}, 2000);
});
});
</script>
</head>
<body>
<div class="wrapper">
<p>The download should start shortly. If it doesn't, click
<a data-auto-download href="auto-download.zip">here</a>.</p>
</div>
</body>
</html>
Zoe
  • 27,060
  • 21
  • 118
  • 148
M. Lak
  • 903
  • 9
  • 18
  • 1
    This answer saves my day. I have a follow up question: if I change "auto-download.zip" to a url like "https://stackoverflow.com/questions/156686/how-to-start-automatic-download-of-a-file-in-internet-explorer.html", it does not work. My purpose is to download the stackoverflow page as html. – halfmoonhalf Jul 18 '20 at 07:58
3

One more :

var a = document.createElement('a');
a.setAttribute('href', dataUri);
a.setAttribute('download', filename);

var aj = $(a);
aj.appendTo('body');
aj[0].click();
aj.remove();
ZettaCircl
  • 835
  • 10
  • 15
2

Be sure to serve up the file without a no-cache header! IE has issues with this, if user tries to "open" the download without saving first.

scunliffe
  • 62,582
  • 25
  • 126
  • 161
1

For those trying to trigger the download using a dynamic link it's tricky to get it working consistently across browsers.

I had trouble in IE10+ downloading a PDF and used @dandavis' download function (https://github.com/rndme/download).

IE10+ needs msSaveBlob.

Community
  • 1
  • 1
Nelu
  • 16,644
  • 10
  • 80
  • 88
1

This seemed to work for me - across all browsers.

 <script type="text/javascript">
    window.onload = function(){
     document.location = 'somefile.zip';
    }
    </script>
Dan
  • 29,100
  • 43
  • 148
  • 207
  • 2
    The lack of such approach is that browser waits for all banners loading... Sometime that takes some time and user is unable to get file due to stupid banners... – Budda Aug 09 '10 at 17:08
  • Except for some browsers + the content is one that could be viewed directly in the browser (like video files), does not actually _force_ the download in all circumstances. – mix3d Sep 08 '19 at 05:50
1

I think this will work for you. But visitors are easy if they got something in seconds without spending more time and hence they will also again visit your site.

<a href="file.zip" 
   onclick="if (event.button==0) 
     setTimeout(function(){document.body.innerHTML='thanks!'},500)">
 Start automatic download!
</a>
cigien
  • 57,834
  • 11
  • 73
  • 112
raheel
  • 11
  • 1
0

Nice jquery solution:

jQuery('a.auto-start').get(0).click();

You can even set different file name for download inside <a> tag:

Your download should start shortly. If not - you can use
<a href="/attachments-31-3d4c8970.zip" download="attachments-31.zip" class="download auto-start">direct link</a>.
Somerussian
  • 381
  • 4
  • 17
  • Not all browsers let you click an anchor tag with JS. Safari, for example, especially if the url is cross-domain – mix3d Sep 08 '19 at 05:52
0
<meta http-equiv="Refresh" content="n;url">

That's It. Easy, Right?

<meta http-equiv="Refresh" content="n;url">
0

This is an old question but in case anyone wants to use automatic download of files with Flask, Python. You can do this:

from flask import Flask, make_response, send_from_directory

file_path = "Path containing the file" #e.g Uploads/images

@app.route("/download/<file_name>")
def download_file(file_name):
    resp = make_response(send_from_directory(file_path, file_name)
    resp.headers['Content-Disposition'] = f"attachment; filename={file_name}"
    return resp

Inside a template or html page, index for example

<div>
  <a class="btn btn-outline-warning" href={{url_for( 'download_file', name='image.png' )}} ">Download Image</a>
</div>

Clicking on the link will download the file without opening another page. For more info on:

lator
  • 29
  • 1
  • 6