2

The HTML5 Offline Web application spec gives an example of how to lazily load HTML pages into the cache:

CACHE MANIFEST
FALLBACK:
/ /offline.html
NETWORK:
*

This is explained in Dive Into HTML5 with the example of Wikipedia: You certainly don't want to cache the entire of Wikipedia when the website loads, but you want any page the user visits to become cached. Any page the user visits while offline should display a custom error page.

The trick of this approach is that each HTML page explicitly includes the manifest. Any page that includes the manifest is automatically included into the cache, without having to be explicitly mentioned. So this example will load HTML pages from the network, and insert them into the cache, and if offline, any page in the cache will work, and any non-cached page will default to the offline.html page.

The problem is for non-HTML files, which have no ability to include the manifest. Specifically, I am writing a game in JavaScript and it has a bunch of music tracks. I have the following requirements:

  • I don't want the user to have to download all the music when the game loads,
  • If the user encounters a new music track while online, that track should be downloaded and cached,
  • If the user encounters a new music track while offline, it doesn't matter if they hear silence.
  • If the user encounters a music track that they have already heard while offline, it should be played from the cache.

Were the music files HTML, I could have used the above technique, and given them a manifest=... attribute to get them into the cache when they are first loaded. But they are not HTML, so I can't do that. Is there any way to get non-HTML resources to be saved to the cache when they are loaded, but not ahead of time?

Note: I'm not very familiar with the traditional HTTP caching mechanism. It's possible that it can be used instead, but in my experience, even if files are cached by the browser, they don't work if the browser is offline. If it's possible to do it this way, how should I configure the cache headers?

µBio
  • 10,668
  • 6
  • 38
  • 56
mgiuca
  • 20,958
  • 7
  • 54
  • 70

2 Answers2

2

That's what Dive Into HTML5 said, but I couldn't find the manifest in Wikipedia. Wikipedia doesn't really work in this way. In my Chrome console, I couldn't find any application cache of Wikipedia.

I think you can try this: When the user has finished downloading a music track, send this info to the server via AJAX. The server should update the manifest for this user and put this music track in it. Then you can call applicationCache.update() to force the browser to check the manifest again and it will discover the update. This means you can't use a static manifest file. The manifest file has to be dynamic and related to user.

Cat Chen
  • 2,387
  • 17
  • 12
  • Note that Dive Into HTML5 isn't suggesting that Wikipedia does this; it's just using it as an example of a website that might be structured that way -- a "hypothetical offline-enabled Wikipedia" as it says. I feel that that suggestion won't really work, because the server will associate the cache per-user, but I want per-browser. If the user moves to a different device that has not downloaded the music, I don't want to force that device to download all the music that user has seen. Perhaps a per-browser cookie would help. Still, this breaks eg. if the user clears her offline cache. – mgiuca Jun 02 '11 at 04:08
  • Is there any way for the client side to query the cache and check what files are in it? If so, the client could tell the server on a per-session basis what music files are already cached, and the server could send back a manifest with those files. It's a dirty hack, but it least it allows the client to manage the cache and not force the server to remember what the cache status is for each client. – mgiuca Jun 02 '11 at 04:10
  • Per-browser and per-user is the same. They both depend on cookie. – Cat Chen Jun 02 '11 at 11:33
  • You can fetch file via AJAX, and you can tell when the downloading it completed. I think the problem is if you update the manifest after the download is finished, there's a chance that the browser has already deleted this download from its cache. – Cat Chen Jun 02 '11 at 11:37
  • No they aren't the same. Per-user depends on a user profile which exists across different cookie sessions. But point taken. This still is not a good solution though, because it requires that the server remembers what is stored on the client, which seems so wrong when the client *is* the client, yet is helpless to remember its own cache. Still, thanks for the suggestion. Since nobody else has suggested anything, I'll give you the tick. – mgiuca Jun 03 '11 at 01:42
1

It looks like Mozilla has exactly the solution, but it only works in Firefox: nsIDOMOfflineResourceList (I don't know why it's called that; these methods apply to the applicationCache object) has methods mozAdd and mozRemove which allow you to dynamically add objects to the cache using JavaScript.

Hopefully that becomes part of the standard (as add and remove); then that would be a proper solution to this issue.

mgiuca
  • 20,958
  • 7
  • 54
  • 70