How PageXchanger and Content Negotiation Make XHTML Safe Enough to Use All the Time

You may already be familiar with some of the things that PageXchanger can do, such as serving correct versions of your pages to users with different language preferences, or serving image files in the optimal format for each user's browser. But did you also know that PageXchanger can help you use the most standards-compliant markup wherever possible, while also maintaining backwards compatibility for browsers that don't support it?

PageXchanger can do this because it is a complete implementation of content negotiation for IIS (actually, it's the only one). And content negotiation is the preferred method for serving XHTML in the most standards-compliant manner possible, while maintaining full support for downscale browsers. The W3C tutorial for how to use content negotiation in this way is online (http://www.w3.org/2003/01/xhtml-mimetype/content-negotiation) but here we will focus on how it's done in PageXChanger which, fortunately for IIS users, makes the process trivially easy.


How MIME Types Work in Your Browser

First, some background. When a Web server sends a page (or really any resource) to a browser, HTTP requires the server to tell the browser how to render that page. This is done is with an HTTP Content-Type header, that has as its value the appropriate MIME type to use in rendering the content. HTML documents classically use the MIME type text/html:




This is the value browsers have come to count on, to tell them they should treat the response as an HTML page. With the advent of XHTML however, the appropriate MIME type changed to reflect the stricter parsing that XHTML presumes. The correct MIME type is now application/xhtml+xml, which means the correct HTTP header now looks like this:




This works perferctly well in a number of browsers, such as Firefox. The new MIME type lets those browsers know to enforce strict XHTML type parsing rules, which in turn means you can validate the pages more strictly as well.


The Problem With XHTML in IE

But there is a problem: Internet Explorer does not yet support this MIME type. Even IE 8 still treats application/xhtml+xml as if it were text/html, refusing to catch malformed markup such as missing or mismatched end tags. Here for instance is a bit of malformed XHMTL, with the appropriate MIME type, as viewed by Firefox:




As you can see, the browser in this case responds to the presence of the genuine XHTML MIME type by enforcing the rules strictly, correctly raising an XML parsing error if the page is improperly coded. Now here is the same page in IE 8, also with the MIME type set correctly:



Worse than that is what happens if you try serving XHTML pages with the proper application/xhtml+xml MIME type to older versions of IE. In some cases, the page won't render at all, regardless of whether it is well- or malformed, and your users will be prompted to download the file, as with this IE 6 version:




In fact, because of this issue with legacy IE browsers, even the most standards-conscious developers and site administrators have typcially had to avoid using the correct MIME type with XHMTL documents, thereby losing some of the built-in advantage of using XHTML to begin with.


Content Negotiation to the Rescue

Fortunately, the perfect solution for this type of problem exists in the form of content negatotiation, which is a nothing but a standards-based technique for serving different versions of a resource to different user agents (browsers). By using content negotiation, you can have the Web server serve the strictly correct XHTML MIME type to browsers that handle it properly, and the more permissive one to browsers that would just ignore it, or worse, choke on it.

In the case of PageXchanger, all it takes to use content negotiation in this way is turning on one optional feature. In the PageXchanger Settings Manager, simply select the Web site for which you want this feature enabled, flip to the Advanced tab, put a check in the box labeled "Enable XHML Mime Type Fix", and click Apply. That's it: you're done.




To test the fix, just open up your Firefox (for example) and navigate to any page that has an XHTML DOCTYPE at the top. If your XHTML is well-formed, it will render; if not, it won't. You can test this yourself by introducing a simple validation error such as transposing two closing tags so that they are crossed rather than nested. If you try the same page in an older version of IE, meanwhile, it will render without incident, whether or not you cross your end tags. That's not ideal, but it's the best that can be done with that browser--and certainly better than confronting the user with a download prompt!




A Look Behind the Curtain

If you're the inquisitive type who likes to see the magic at work, you go can still farther and use HTTP protocol sniffers that plug into your browser (like LiveHttpHeaders for Firefox and IEHttpHeaders for IE) to examine the HTTP headers being returned by IIS and PageXchanger. What you will see is that, in the case of Firefox, the Content-Type HTTP header will have a value of application/xhtml+xml, whereas, in the case of IE (even IE 8), it will be set to the less-strict but safer text/html:






If you examine the address bars in the two screen shots above, you will see that these two different versions (or "representations" in HTTP-speak) of the same resource are being from the same URL. How is that possible?

Well if you use your protocol analyzers to look not just at the response headers, as we've been doing, but also at the request headers on the first request for that same page, you'll see that Firefox issues an Accept request header that explicitly includes the native XHTML MIME type (application/xhtml+xml) among one of the MIME types it can accept:




This is the browser's way of telling the server it can accept such content and IIS (with PageXchanger's help) responds accordingly. If you look at the Accept header sent by IE, on the other hand, you will see that the application/xhtml+xml MIME type is nowhere to be found--even in the case of IE 8, which uses the Accept header to announce its ability to handle quite a few other special MIME types, but not this one:




And that is why, in the case of IE, PageXchanger makes IIS respond with the old fashioned text/html MIME type, even though the page itself calls for strict enforcement of an XHTML DTD. This way, both types of browser are happy, and you get the benefit of strict XHTML enforcement, without running the risk of shutting out users with downscale browsers.

And that is content negotation in action: promoting the latest in Web standards while safeguarding backwards compatibility. And all it took was turning on one feature in PageXchanger. Imagine what you could accomplish with the rest of its content negotiation capabilities at your disposal!