Change IE compatibility in JSF

Developing for internet explorer is a pain, due to them not adhering to standards for html, css, javascript and almost everything web related. Thankfully they have started following the standards all the other major browers use. The problem now is all the sites that were made to work in IE7, break in newer the newer versions that follow the standards. To fix this, microsoft introduced a compatitility mode in IE. The browser some how detects which version your website is made for, by looking at things like the DOCTYPE and tags specific to different IE versions. The problem is that it doesn’t always work and your site breaks, because IE turns on compatibility mode, even when the site follows the standards.

To fix this, microsoft has defined a meta tag you can put in your HTML, so you can override which IE version is chosen in compatibility mode. This can be because your site uses IE7 only markup and to make sure that it still works in newer browsers, you can tell IE to switch to IE7 mode. It could also be that you want to force IE to use the newest version, when it deceides to use the wrong version.

To do this you add the following META tag:

 <meta http-equiv="X-UA-Compatible" content="IE=9" >

More information about the X-UA-Compatible meta tag can be found here: http://msdn.microsoft.com/en-us/library/cc288325(v=vs.85).aspx

However, this won’t work if you use JSF to develop your website. The meta tag must be before any javascript, for IE to recognise the tag. This is not possible in JSF mojarra, since it puts the JSF related javascript before all other tags in the head element. Instead you must insert it into the header of the HTTP request.

This is done using a filter:

package eu.joensen.filter;

import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;

public class IEFilter implements Filter {

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletResponse res = (HttpServletResponse) response;
		res.addHeader("X-UA-Compatible", "IE=Edge");
		chain.doFilter(request, response);
	}

	@Override
	public void destroy() {
	}
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}
}

This takes the response before it is delivered to the browser and adds a X-UA-Comaptible header field, where the value is which version you wish to enforce. I have chosen the Edge version, which is the latest version of IE, even when new versions are released.

To add the filter, you must add some configuration in the web.xml file:

	<filter>
		<filter-name>IEFilter</filter-name>
		<filter-class>eu.joensen.filter.IEFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>IEFilter</filter-name>
		<url-pattern>*.xhtml</url-pattern>
	</filter-mapping>

First the filter is registered, where the filter-name is a string you choose. The filter-class is the java class you made to filter the response. Secondly you add a fitler-mapping, where you put the chosen filter-name in the first field and the expression to be filtered on in the url-pattern element in the second.

The HTTP reponse:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-UA-Compatible: IE=Edge
Accept-Ranges: bytes
ETag: W/"453-1322401175000"
Last-Modified: Sun, 27 Nov 2011 13:39:35 GMT
Content-Type: application/xhtml+xml
Content-Length: 453
Date: Sun, 27 Nov 2011 13:39:45 GMT