The Content-Disposition Saga: Controlling the suggested file name in the Browser's Save As Dialog
Sometimes when I'm dynamically generating a graphic on the server side, perhaps a chart or graph, or I'm retrieving a check image via Web Services, the user wants to save the time, and I want to control the file name that is suggested in the File|Save As Dialog. Most often the browser will just recommend the page's file name (the one that was part of the HTTP GET request). So, how do you control the suggested Save As filename?
UPDATE: Here's how you do it in IE8.
Well, you do and you don't. There's a HTTP Header called Content-Disposition (case senstitive) that is NOT part of the HTTP standard, but rather it's own Request for Comments, RFC 1806.
HTTP Headers are name values pairs, so they are easily added with the Response object in ASP or ASP.NET You use it like this (the HTTP Headers):
HTTP/1.1 200 OK
HTTP/1.1 200 OK
Content-Disposition: attachment; filename=checkimage.jpg
Here's a list of gotchas, starting with my own:
- On IE 6.0, things mostly work, but if you ALSO setup Cache-Control: no-cache, your suggested filename (and type!) will be IGNORED. A bummer if you have to choose between security and convienence. Of course, security wins.
- On IE 4, the attachment option is flaky, see Q182315
- On IE 5.5, the attachment option is REALLY flaky, see Q267991 and Q279667 and Q281119
- On IE 5.0, the filename suggested can mangle your filenames, see Q262042
- On nearly all versions of IE, including 6.0, sometimes the browser will use the filename in the address bar instead of the Content-Disposition Header, and with IE5.5SP2 you're expected to change the UseCDFileName registry key, see Q303750. This was fixed with IE6.0SP1.
Also, there are some security issues around Content-Disposition, like suggesting evil names of files to make a careless user overwrite /etc/passwd, etc, that were included in the updated RFC 2183.
For classic ASP folks, here are some good code samples around Content-Disposition.
It's a shame that this can't just work as the spec was written, and it's taken 2+ versions of IE to still get it wrong.
Note: Remember, if you want to sniff your own HTTP Headers, do it with class and use Jonas Blunck's iehttpheaders.