XSLT not working with separate web server using BEA plugin (wrong Content-Type)
We use client side XSLT to generate our pages. After a push to our testing environment, we noticed that the XSLT would fail in Firefox but not IE.
Environment
The testing environment consists of a hardware load-balancer, two apache web servers and a two instance weblogic server cluster. The web servers communicate with weblogic via the standard weblogic plugin.
Cause
This problem didn't occur on our local development boxes. In order to figure out the problem we had to isolate the differences between testing and development and eliminate those differences from the test.
First thing we did is hit the web servers directly, bypassing the load balancer-- no change. Next we hit the application server directly, bypassing the load balancer and web servers-- everything worked like development. After those two tests, we knew that something was different with how the XSL file was being served when we used the web server vs. the application server.
This didn't really explain the FF vs. IE problem though. Since the problem was in FF (for a change), I could actually use Firebug to see what was going on. After setting a break point inside the javascript method that was going to perform the XSLT, it was clear what the problem was. The variable that held our XSL document was empty. I looked inside the Net view just to make sure that the content was coming back from the server and it was. It had to be, how else would it work in IE?
Turns out that the Content-Type was wrong. When I was hitting the application server directly the Content-Type was not put in the response header; FF and IE both accept this and create an XMLDocument from the response. When I hit the web server the Content-Type was specified as text/html; IE still creates an XMLDocument from the response but FF does not.
Solution(s)
Ok so the problem is that the Content-Type is incorrect on the response to the XSL request. There are two obvious solutions to this issue:
- Serve the XSL from the web server and make sure the Content-Type is mapped in the web server's config.
- Serve the XSL from the application server via the web server plugin and change the Content-Type from text/html to application/xml.
Solution #1 makes a lot of sense if the XSL is a static document. We all know that web servers do really well with static content. In order for this to work, you'll need to set the WLExcludePathOrMimeType plug-in configuration parameter properly. Once you add *.xsl to the list the plug-in will stop forwarding XSL requests to the application server.
Solution #2 makes sense if you are dynamically creating XSL documents or as a fall back if solution #1 was missed somewhere. What you need to do is modify the web.xml file for your web application and add a mime mapping:
<mime-mapping>
<extension>xsl</extension>
<mime-type>application/xml</mime-type>
</mime-mapping>
Conclusion
Once I added the mime mapping to the web.xml, the Content-Type was always put into the response header regardless of the access method. Both FF and IE rendered the pages successfully. Ultimately, the XSL files were being served from the web server with the mime type being managed by apache. But it is nice to know that the application still functions properly if XSL requests get forwarded to the application server cluster.
