views:

687

answers:

1

I'm looking for some more thoughts about the best way to initiate a file download from Javascript.

http://stackoverflow.com/questions/60590/best-way-to-initiate-a-download has a lot of good ideas which can be summarized:

  • Set the src on an iframe
  • Use window.location.replace()
  • Use a page with a meta refresh header
  • Use a window.open()
  • Let the server directly output file, setting the Content-Type and Content-Disposition
All of those approaches work fine for the browsers I've been testing with, except for IE8. With IE8, I get a bunch of problems:

  • The iframe isn't working because of cookies set by the environment I'm using. I think I'd need to enable P3P headers to resolve this, but the environment doesn't allow me to set headers, so P3P is out
  • The window.location.replace() works except that in IE8, the address bar of the window changes to the URL to the file and the underlying window is blank after the downloaded file is opened
  • The meta refresh approach also works, but still the address bar changes to the URL of the file and the underlying window is blank after the file downloads
  • I'm desperately trying to avoid window.open() to dodge any popup blocker problems
  • The server environment I'm in won't allow you to output the file itself, like you could do in say, ASP.NET's Response object

I haven't even tried these methods with IE6 or IE7, so there may be other surprises there.

So does anyone have any other suggestions for initiating a download in IE, where (1) no popups are involved and (2) the file can be saved or opened and (3) no blank window is left behind, (3) using just Javascript, HTML and a URL to a file?

Denver Mike

+2  A: 

The usual pattern for a download-file page (if you must have one; personally I hate them) is either:

<script type="text/javascript">
    window.onload= function() {
        window.location= document.getElementById('downloadlink').href;
    }
</script>
<p>
    Your download will begin shortly. If it doesn't,
    <a id="downloadlink" href="file.zip">click here</a>.
</p>

Or the same with a meta-refresh instead of the script. Either way should behave pretty much the same.

The meta refresh approach also works, but still the address bar changes to the URL of the file and the underlying window is blank after the file downloads

That shouldn't happen. Is there a version online that can be tested? Normally, when the browser is pushed to a direct file download by any normal method (link click, location.href, meta-refresh), it should keep the previous page on-screen.

the environment doesn't allow me to set headers, so P3P is out

You don't have to use headers to set P3P policies, an HTML <link> tag works just as well:

<link rel="P3Pv1" href="/policy.p3p" />

But why would you need to? If the target URL is just serving a file, there is no need to set a cookie at all, so why bother with P3P?

I'm desperately trying to avoid window.open() to dodge any popup blocker problems

If you window.open() in response to a user click, there are no pop-up blocker problems.

Not that you should need to open a pop-up just to download a file anyway. I am beginning to think there is something highly strange about the file download destination you are linking to — like it's not a file download at all but some kind of odd HTML web app. Linking to a download is not hard, you just link to the file, job done; you seem to be making this much harder than it intrinsically is.

The only usual problem with just linking to a file is that if it contains text, HTML, XML or an image, the browser will display it inline instead of downloading it. The only way to defeat this is using the ‘Content-Disposition: attachment’ header, either by serving it through a script that sets this header, or by configuring your web server to send that header for all file downloads. If you can't do either of those in your server environment, there is no solution.

bobince
Thanks very much for your detailed comments and excellent tips. I've decided to simply provide a link to download the file and it works great in all browsers and avoids all of this complication.