Use Content-Disposition to Send a File
While we’re on the subject of magic header incantations, servlet developers often struggle with finding the right header combination to send a browser a file that’s intended for saving rather than viewing and thus triggers a “Save As” dialog. For the solution to this problem, I have some good news and some bad news.
The bad news is that although the HTTP specification provides a mechanism for file downloads (see HTTP/1.1, Section 19.5.1), many browsers second-guess the server’s directives and do what they think is best rather than what they’re told. These browsers—including Microsoft Internet Explorer and Opera—look at the file extension and “sniff” the incoming content. If they see HTML or image content, they inline-display the file contents instead of offering a Save As dialog.[5] Turns out there’s no 100% reliable way to download a file across all browsers. Perhaps, with this effort, programmers are more like alchemists than magicians, trying in vain to turn lead into gold.
The good news is that the right combination of headers will download files well enough to be practical. With these special headers set, a compliant browser will open a Save As dialog, while a noncompliant browser will open the dialog for all content except HTML or image files. For these types it will display the content inline, where a user can use the menu to save the content. Example 3-9 shows the best technique for sending files.