Making IE Accept File Downloads

Posted on October 1st, 2004

I’ve been adding more report features to our internal web app at work. Getting them to the point they are at now is another story, for now let me tell the tale of convincing Internet Explorer (IE) to download a comma separated value (CSV) version of these reports. Here is the situation, a secure (SSL) connection to Apache to an internal website written in PHP talking to a PostgreSQL database with IE 6 on the client end. The initial version of the reports just displayed in an HTML table as part of the site. It was suggested that the data should be available as CSV so that employees could easily manipulate or graph the data in Excel. Sounded reasonable enough. After a couple of tries it looked like I had everything working. All of my initial tests were done using Firefox on Windows, with a little bit of testing using Safari on OS X. I know we still have some folks at work who are still using IE (that too is another story) so I tested that one out last. Everything worked, right up until I tried to download the CSV version of the reports.

Instead of prompting me with a dialog box to determine if I wanted to open the file or save, IE simply came back and indicated that it couldn’t save the file and presented with me with one option, ‘OK’. Of course ‘OK’ isn’t really ‘OK’, because it terminated the download and dropped me back into the website. Just great, I thought I was pretty much done and then IE showed its unpleasant side. Knowing that someone else must have ran into this problem I went on a hunt for a solution. After trying out several ideas over a couple of hours I came across the solution. Here is what I believe to be the minimum solution to make IE correctly download a file presented to it from PHP.

First, when talking to IE there is an additional session parameter that must be set for the download to work (this was the last piece of the puzzle that I found). This has to be done before starting the session.

    if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE')) {
        session_cache_limiter("public");
    }
    session_start();

Once you have built your CSV string and are ready to send it to the browser you’ll need to add a couple of headers first.

    header('Content-type: application/octet-stream');
    header('Content-Disposition: attachment; filename="report.csv"');
    print($csv);

Now that it all seems to be working it doesn’t look very impressive, but it was certainly disappointing to have my initial solution work in Safari, Firefox and Opera but not IE. I hope this saves someone else the hours I spent figuring out why IE hates me.