AppCache and SSL


We have just hit a bit of an issue with AppCache whilst we were deploying a new version of a client site. It’s not really a bug, but more a lack of clarity in the current documentation and different implementations in the browsers.

It has taken me sometime to understand how the NETWORK: section of the AppCache actually works. In the end, I had to build a series of AppCache tests to figure it out.

The story

We setup the NETWORK: section of the AppCache to point at a rest API


# This code is an incorrect use of AppCache

Breaking AppCache

As we deployed our site we wanted to run the API that is on another domain under SSL. So we changed the URL in the NETWORK: section so it started with https and added the certificate to the site. i.e.


# This code is an incorrect use of AppCache

At this point Chrome stopped making API requests, we were only initially testing with Chrome.

First mistake – putting the * wildcard in the wrong place

Our first mistake is that we wrongly added the * wildcard to the end of the URL. Each entry in the NETWORK: section can be one of three types. These entries are usually added as a new line directly under the NETWORK: section header. The entry types are:

  • * wildcard on its own
  • relative or absolute URL
  • URL “Prefix match”

Examples of the correct use of AppCache NETWORK: section


“Prefix match” URL

A “Prefix match” is a strange concept – it’s a URL that is used as a “starting with” matching pattern. If your API has many endpoints but they all live in the path then that’s all you need to add to the NETWORK: section. The * wildcard can only be used on its own and means any URL.

Second mistake – URLs should have the same protocol and domain as the manifest

There are other rules that effect the use of URLs in the NETWORK: section. All URLs have to use the same protocol scheme i.e. http or https and be from the same domain as the manifest.

Browser implementations of these rules do differ, Firefox is strict and insists on the same domain, where as other browsers only insist on the same protocol scheme. See the test examples I have built to demonstrate this.

In effect, that means to get good support across the major browsers you can only use URLs in the NETWORK: section if they are to the same domain as the manifest.

The fix is to use the * wildcard and not URLs

The vast majority of sites sidestep the complexities of URLs, by just applying the * wildcard on its own i.e.


This will work with the manifest on one scheme (http) and the API on another (https). The wildcard does not have the same rules as URLs.

You have to ask why the hell the authors of the specification added all this complexity if all that happens is that everyone applies the * wildcard.

Thanks to Jake Archibald for some pointers to the answers as I waded my way through this.

  • html5 appcache