Fixing the ‘Do you want to display nonsecure items’ message

calendarApril 30, 2008 in Caching , HTTP , HTTPS , HttpWatch , Internet Explorer

Have you ever been to a web site and seen this?

Non secure items warning in IE

This warning is triggered in IE if it is displaying a secure HTTPS page that has caused a non-secure (i.e. HTTP based) resource to be downloaded. The message box doesn’t allow the user to control whether the non-secure content should be downloaded, only whether it should be displayed.

This seems rather pointless as the damage may already have been done if the non-secure content was a picture of your passport, bank statement or credit card! However, this is the default setting in IE so it is best to avoid this warning being generated on your web site.

This setting can be changed in IE by:

  1. Going  to Tools->Internet Options->Security
  2. Select the Security tab
  3. Click on the Internet zone icon at the top of the tab page
  4. Click the Custom Level button
  5. In the Miscellaneous section change Display mixed content to Enable
  6. Repeat steps 1 – 5 for the Local intranet and Trusted sites zones

Recently, we saw this warning in the shopping cart of an  computer store,  so we fired up HttpWatch to see what was causing the problem. A quick search for a URL starting with ‘http:’ should have located the request causing the problem:

HttpWatch trace for nonsecure items message at Ebuyer

No HTTP requests were recorded for this page in HttpWatch. So what was causing the ‘Do you want to display nonsecure items’ message?

It turns out that IE warns about HTTP based content even if it was read from the browser cache or the IE image cache. Requests from the browser cache are shown as (Cache) in HttpWatch, but as we previously described access to the IE image cache is not recorded.

The resource causing the warning on this page must have been read from the image cache. We confirmed this by refreshing the page in IE and performing another search:

Image causing nonsecure items warning

The refresh forced IE to download all the embedded resources on the page and it became clear that it was the Google Checkout image that was causing the problem. Changing this image’s URL to use HTTPS would prevent the warning from appearing.

The Performance Benefits of Ajax

calendarApril 18, 2008 in HTTP , HttpWatch , Javascript , Optimization

Web 2.0 is a term often used to describe next generation web sites that have moved beyond the simple page request->process->response cycle and are utilizing services on the web server to return data that can be rendered without making page transitions. The result is often a more responsive user interface that closely mimics a desktop application.

The technology to make HTTP calls from JavaScript embedded in an HTML page was first introduced for general use by Microsoft in IE5 in order to support Outlook Web Access way back in 1999. However, the XmlHttpRequest object was not widely used until it was adopted by Mozilla in 2002. In 2005 the programming model was given the name Ajax which has now been widely recognised and stands for Asynchronous JavaScript + XML.

From a performance perspective Ajax has two main benefits:

  1. It can reduce the number of round trips by minimizing the number of page transitions in a web application
  2. It can reduce the size of uploaded and downloaded data because it allows the web programmer to control exactly what is transferred. For example, if a user performs a search the data can be returned in a compact data format (e.g. JSON ) rather than HTML.

In order to illustrate how Ajax can increase the speed and usability of a site let’s first look at a traditional web site and then compare it to an Ajax example.

This is what happens on Expedia.com when we try to book a flight but we specify a partial or mispelled city code. In this case we typed in “LOND” instead of “LON” or “London”. We expectantly press the submit button hoping for a list of possible flights, but instead we’re directed to an error page:

Expedia Error Page

Using HttpWatch we can see that Expedia took 4.4 seconds, 30 round trips and 156K of data (of which 41K was uploaded)  to display the error page:

Expedia Error Page Summary

Even if there are no further mistakes we will still have to make further page transitions before we get the results we’re expecting.

Let’s look at a similar example on BA.COM where Ajax has been used:

BA Cities List

Here we did exactly the same thing – typed “LOND” instead of London. Instead of having to press submit, fetch a new choices page (with all linked page components) and drag the user through an additional form, the page used background processing to query the server and display a list of possible choices.

The beauty of this approach is that is that it didn’t require any user interaction, is very fast and it didn’t leave the search page. Here’s the Ajax request in HttpWatch:

BA Ajax Request

BA.COM uses the DWR framework for Ajax to request the possible airports. The framework returns a JavaScript list used to render the content into the dropdown list control. The single HTTP call required is much smaller and faster than the Expedia model where the whole page must be fetched and rendered.

Due to the inconsistencies between the programmable object models on different browsers, most developers now choose a framework to ease JavaScript development and most provide Ajax helper functions that wrap XmlHttpRequest. Java’s DWR has RPC style support. ASP.Net’s Ajax library, Dojo, Yahoo’s YUI and Google’s GWT support a whole suite of UI and control extensions as well as offering some kind of Ajax support. Similarly, Prototype and jQuery are two extremely lightweight and popular JavaScript libraries.

Let’s say you wanted to populate a list box with city codes based on the country a user selects. In Web 1.0 you would have to submit a form making a round-trip to the server with your choice of country so that the server could render the appropriate list of choices on the resulting HTML page.

With Ajax, this can all be done in the background. A lot of services use the XML data format, but there’s no restriction on the content type that XmlHttpRequest can send or receive. It could be HTML, JSON or any other format that the page’s JavaScript can parse.  Here’s an example of using the jQuery library to populate a list control from an Ajax request:

<script type="text/javascript" src="jQuery.js"></script>
...
<h2>Products</h2>
<div id="products">(fetching product list ...)</div>
<script>
...
jQuery("#products").load("productListHTML.aspx");
...
</script>

The products <div> is initially empty, but the load() method wraps XmlHttpRequest and fetches some HTML from the server and uses it to populate the <div>.

One of the drawbacks people found with using Ajax was that they ended up breaking the back button. Clicking the Back button in some Ajax applications did not go to the previous logical operation. For example, if you were viewing the results of a search you would expect Back to take you to the search page so that you could modify the search criteria. Instead, the user would be taken to whatever happened to be the previous page in the browser’s history list.  In some cases, they may even have been the previous web site that the user had visited.

More recently though, browsers have exposed object models to help Ajax applications manipulate the browser history artificially so that they can correct the flow of operations as the user uses the forward and back buttons.

Two Simple Rules for HTTP Caching

calendarDecember 10, 2007 in Caching , HTTP , HttpWatch

In practice, you only need two settings to optimize caching:

  1. Don’t cache HTML
  2. Cache everything else forever

“Wooah…hang on!”, we hear you say. “Cache all my scripts and images forever?

Yes, that’s right. You don’t need anything else in between. Caching indefinitely is fine as long as you don’t allow your HTML to be cached.

“But what about if I need to issue code patches to my JavaScript? I can’t allow browsers to hold on to all my images either. I often need to update those as well.”

Simple – just change the URL of the item in your HTML and it will bypass the existing entry in the cache.

In practice, caching ‘forever’ typically means setting an Expires header value of Sun, 17-Jan-2038 19:14:07 GMT since that’s the maximum value supported by the 32 bit Unix time/date format. If you’re using IIS6 you’ll find that the UI won’t allow anything beyond 31-Dec-2035. The advantage of setting long expiry dates is that the content can be read from the local browser cache whenever the user revisits the web page or goes to another page that uses the same images, script or CSS files.

You’ll see long expiry dates like this if you look at a Google web page with HttpWatch. For example, here are the response headers used for the main Google logo on the home page:

Google Expires header

If Google needs to change the logo for a special occasion like Halloween they just change the name of the file in the page’s HTML to something like halloween2007.gif.

The diagram below shows how a JavaScript file is loaded into the browser cache on the first visit to a web page:

Accessing page with empty cache

On any subsequent visits the browser only has to fetch the page’s HTML:

Read from cache

The JavaScript file can be read directly from the browser cache on the user’s hard disk. This avoids a network round trip and is typically 100 to 1000 times faster than downloading the file over a broadband connection.

The key to this caching scheme is to keep tight control over your HTML as it holds the references to everything else on your web site. One way to do this is to ensure that your pages have a Cache-Control: no-cache header. This will prevent any caching of the HTML and will ensure the browser requests the page’s HTML every time.

If you do this, you can update any content on the page just by changing the URL that refers to it in the HTML. The old version will still be in the browser’s cache, but the updated version will be downloaded because of the modified URL.

For instance, if you had a file called topMenu.js and you fixed some bugs in it, you might rename the file topMenu-v2.js to force it to be downloaded:

Force update with new file name

Now this is all very well, but whenever there’s a discussion of longer expiration times, the marketing people get very twitchy and concerned that they won’t be able to re-brand a site if stylesheets and images are cached for long periods of time.

In fact, choosing an expiration time of anything other than zero or infinite is inherently uncertain. The only way to know exactly when you can release a new version to all users simultaneously is to choose a specific time of day for your cache expiry; say midnight. It’s better to set indefinite caching on all your page-linked items so that you get the maximum amount of caching, and then force updates as required.

Now, by this point, you might have the marketing types on board but you’ll be losing the developers. The developers by now are seeing all the extra work involved in changing the filenames of all their CSS, javascript and images both in their source controlled projects and in their deployment scripts.

So here’s the icing on the cake; you don’t actually need to change the filename, just the URL. A simple way to do this is to append a query string parameter onto the end of the existing URL when the resource has changed.

Here’s the previous example that updated a JavaScript file. The difference this time is that it uses a query string parameter ‘v2’ to bypass the existing cache entry:

Force update with query string

The web server will simply ignore the query string parameter unless you have chosen to do anything with it programmatically.

There’s one final optimization you can make. The Cache-Control: no-cache response header works well for dynamic pages as it ensures that pages will always be refreshed from the server; even when pressing the Back button. However, for HTML that changes less frequently it is better to use the Last-Modified header instead. This will avoid a complete download of the page’s HTML, if it has not changed since it was last cached by the browser.

The Last-Modified header is added automatically by IIS for static HTML files and can be added programmatically in dynamic pages (e.g. ASPX and PHP). When this header is present, the browser will revalidate the local, cached copy of an HTML page in each new browser session. If the page is unchanged the web server returns a 304 Not Modified response indicating the browser can use the cached version of the page.

So to summarize:

  1. Don’t cache HTML
    • Use Cache-Control: no-cache for dynamic HTML pages
    • Use the Last-Modified header with the current file time for static HTML
  2. Cache everything else forever
    • For all other file types set an Expires header to the maximum future date your web server will allow
  3. Modify URLs by appending a query string in your HTML to any page element you wish to ‘expire’ immediately.

Ready to get started? TRY FOR FREE Buy Now