Tuesday, October 11, 2011

Server-side fix for Mixed Content problem with IE

Many times when hosting your web application over HTTPS, you get a popup on IE which reads:

This page contains both secure and nonsecure items. Do you want to display the nonsecure items?

You might find various ways to fix this problem by altering IE settings, but that would just prevent the popup from being shown to the user and not resolve the problem. Anyways it is not feasible to ask every user to add the website to trusted sites or keep clicking the "Yes" button every time the page loads.

Cause: As correctly displayed by the error message (Its surprising that sometimes Windows gives a correct error description as well :D ) the root cause of the problem is that your page is rendered using content from different sources some of which run on HTTP and others on HTTPS. Hence although the URL shows secure socket connection, but the page might transfer some information over nonsecure connection as well.

Solution: Following steps can be followed to solve the problem:

1. Alter page source to read all contents from single protocol: Change the web page source such that all the components in the page come from either HTTP or from HTTPS protocol. Make sure to remove any protocol specific URLs. All the page components like stylesheets, JavaScript files, images etc should contain relative URLs so that they work with both HTTP and HTTPS protocols. For example change
<img src="http://www.w3schools.com/images/home.gif" /> 
To
<img src="/images/home.gif" />
This will let your web browser pick the protocol automatically. Also if your web page uses any third party widgets like Youtube Video, Google Maps etc., look for HTTPs services for these widgets.

2. Remove all empty/null/blank links: When IE comes across a blank/null link; it tries to search for a page in the same folder as the URL and uses HTTP protocol for the same. If it is required to keep blank links which are dynamically populated using client side scripts, then initialize them with a dummy HTML page. HTML pages are faster as they can be cached by Web Container as well as Browser. For example change
<iframe src=”” name=”my_frame”>iframe with empty src</iframe>
To
<iframe src=”<root>/blank.html” name=”my_frame”>now blank</iframe>

3. Remove void JavaScript declarations: Remove any javascript:void(0); statements and replace them with actual functions. For example change
<a href=”javascript:void(0);” onclick=”my_function();”>Click Me</a>
To
<a href=”javascript:my_function();”>Click Me</a>
This will make your anchor robust as now your anchor can respond to Space/Enter keys along with mouse click.

4. Abstract any HTTP requests behind HTTPS: In case any of the above solutions is not possible and some third party resource can be hosted only over HTTP, you can create a Servlet which can abstract the HTTP resource for the client. For example I need to use a CSS from another department which is hosted only over HTTP. I can create a ResourceServlet which would fetch the CSS for me. I would map the Servlet against required-css-file.css so that HTTPS request is intercepted by my servlet which fetches the CSS over HTTP and returns back the CSS over HTTPS.
 





No comments:

Post a Comment