Jaa


IE9 Standards Mode Accepts only text/css for stylesheets

I recently encountered a blog that isn’t looking right in IE9:

image

The site renders just fine in other browsers, and when the page is put into Compatibility View by ticking the icon in the address bar:

image

What’s going on here? It’s clear that a stylesheet isn’t being applied, but why not?

While IE9’s F12 Developer Console logs a notification if a server provides an incorrect MIME type for a stylesheet response, no explicit console notification is provided when the stylesheet download fails; developers will need to use the F12 Network tab or Fiddler to troubleshoot the download failure.

The root of the problem quickly becomes obvious when Fiddler is watching the traffic. For IE9 running in Standards Mode, the site is returning a HTTP/406 response to the browser for the key stylesheet:

image

When the stylesheet fails to download (see the red entry above), IE has no styles to apply and the user sees unstyled HTML.

What’s different about IE9 Standards Mode?

IE9 Standards Mode corrects a longstanding limitation whereby earlier versions of IE would improperly send an Accept: */* request header for all resources in a page. That header suggested that IE would be perfectly happy with any Content-Type returned by the server.

While always misleading, that is now outright wrong in IE9—for security and standards reasons, IE9 Standards Mode requires stylesheet responses have a text/css MIME type. If they do not, the browser will not attempt to load the response as a stylesheet. IE9 communicates this requirement to the server by specifying that it will only accept text/css responses when a HTTP request is made for a stylesheet.

It turns out that this server has a bug whereby it returns a HTTP/406 Not Acceptable response when the browser specifies that it will only accept a text/css response… in spite of the fact that the response content actually is text/css. A look at the response headers on the HTTP/406 response provides a clue as to what the problem may be:

HTTP/1.1 406 Not Acceptable
Server: Apache
Alternates: {"serendipity.css.php" 1 {type application/x-httpd-php}}
Vary: negotiate,Accept-Encoding
TCN: list
Content-Type: text/html; charset=iso-8859-1

The Alternates header suggests to me that the CSS file in question is generated by PHP, but the webserver software thinks that PHP files will always be served with an application/x-httpd-php MIME type. With this misunderstanding, the web server refuses to actually run the PHP file and thus never realizes that the PHP file will itself set the proper text/css MIME type.

With their Accept headers, Firefox, Chrome and Opera all imply that they will accept any MIME type for a stylesheet response, although like IE9 they too will not apply a stylesheet that bears an incorrect MIME type.

Internet Explorer 9 users can workaround the site’s bug by putting the site into Compatibility View. In Compatibility View, IE reverts to its legacy behavior of claiming to accept any MIME type for subdownload requests, and the server returns the response without complaint.

-Eric Lawrence

Comments

  • Anonymous
    March 27, 2011
    Similar situation for javascript, it appears. There are a few folks out there that hotlink javascript from the github repo.. Those are served with text/plain and IE9 doesn't evaluate them. modernizr.github.com/.../output.html is an example.

  • Anonymous
    March 27, 2011
    @Paul: That's actually a rather different problem. They're serving their JavaScript as text/plain AND they're sending X-Content-Type-Options: nosniff, informing the client that this is the definitive MIME-type and the response type should not be sniffed to anything else. That's covered here: blogs.msdn.com/.../mime-handling-changes-in-internet-explorer.aspx and here: blogs.msdn.com/.../ie9-beta-google-image-search-javascript-content-type-and-nosniff.aspx

  • Anonymous
    March 27, 2011
    The comment has been removed

  • Anonymous
    March 27, 2011
    Thanks for the headsup. It seems it is a long-standing bug[1] between Apache, mod_negotiate, PHP & IE9's change in behaviour. I've disabled MultiViews as I don't really need them and got the following on testing, which looks good: GET singe.za.net/.../serendipity.css HTTP/1.1  Request Headers:     Host[singe.za.net]     User-Agent[Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)]     Accept[text/css]     Accept-Language[en-us,en;q=0.5]     Accept-Encoding[gzip, deflate]     Accept-Charset[ISO-8859-1,utf-8;q=0.7,*;q=0.7]     Keep-Alive[115]     DNT[1]     Connection[keep-alive]  Response Headers:     Date[Mon, 28 Mar 2011 07:55:56 GMT]     Server[Apache]     Status[200 OK]     Set-Cookie[REDACTED; path=/     Expires[Mon, 28 Mar 2011 08:55:56 GMT]     X-Session-Reinit[true]     Vary[Accept-Encoding]     Content-Encoding[gzip]     Content-Length[2542]     Keep-Alive[timeout=15, max=100]     Connection[Keep-Alive]     Content-Type[text/css; charset=UTF-8] [1] www.gerd-riesselmann.net/.../beware-of-apaches-multiviews

  • Anonymous
    March 30, 2011
    The comment has been removed

  • Anonymous
    March 30, 2011
    The comment has been removed

  • Anonymous
    April 04, 2011
    The comment has been removed

  • Anonymous
    April 18, 2011
    IMHO, the other browsers should follow IE on this one.