On the Web, no one knows you’re a dog
… unless you are served with the proper HTTP headers.
What makes a CSS stylesheet a CSS stylesheet, and not just a text file that happens to look a lot like CSS? What may sound like an abstract philosophical reflection on the ontological nature of Web resources, became a very practical issue around 2002, when one of the major Web Browsers was patched to take HTTP information seriously, and would ignore stylesheets unless they were properly served as such by the web servers.
To understand what happens, one needs to look into the process of delivering resources on the Web: whenever a resource is requested, and served, by a Web server, it isn’t sent on its own: the server prepends a lot of important information in the HTTP Headers. That information can be about the size of the representation served, caching directives, character encoding. And, among the most important: the media type. This is where the server tells the client “please treat this as a jpeg image/css stylesheet/xml document”. That information is authoritative, and if a server declares “this is text/plain”, clients have to treat content as plain text, even if it happens to look like HTML, CSS, or a PNG image. Guessing against this information is considered a bad idea.
The importance of this information provided by the
Content-Type HTTP header means that one may sometimes want to set, or force, the served media type for a resource, or many. Let’s look at a few techniques for a number of practical cases.
Static resources: set up a web server, leverage its defaults
Many resources on the web are “static”, that is, they are equivalent to files sitting on, and served by the Web server.
For those, the most simple way to set up the media type served by the server is to use a recognized file extension. For instance,
a file with extension .css will automatically be served as
text/css, files with extension .html and .xhtml will automatically trigger content-types
Sometimes, however, one may want to force a specific mime type for a resource, regardless of what the static file is, or add a media type to the configuration of the Web server. For instance, we recommended in the Web Standards Do that one may want to server XHTML files as
text/html for public consumption (at least for as long as XML support in generic browser remains weak), but use the stricter parsing of
application/xhtml+xml for testing purposes. For such cases, each Web server has a different way of configuring the media types:
- the Apache web server has the
AddTypedirective to set up a new recognized media type for a given file extension, and the
ForceTypedirective to force the determined media type of a given resource.
- Microsoft IIS server can also be configured to serve specific mime types. This technet note describes the procedure, and lists the known media types, and the file extensions that will trigger their recognition.
- this tutorial has info on Tomcat (among others).
Dynamic Scripting Languages
Not all Web resources are static, and a growing number of them are actually generated by “CGI” or dynamic scripting engines. Below are examples of setting the
Content-Type header with such languages.
- Perl programmers on the web are often familiar with the
print "Content-type: text/htmlnn";statement. Object-oriented code can also use the
HTTP::Headersmodule to set this HTTP header and others.
- PHP has a
header()function for this purpose.
- Python has
print "Content-Type: text/html". the WSGI module also has
- for ASP and ASP.NET, use: Response.ContentType = “text/html” — If you’re using C# in ASP.NET, just add a semicolon at the end of the statement. (Hat tip: Asbjørn Ulsberg)
If your favorite language is not listed, feel free to share your techniques in the comments below.