This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 20678 - API to expose HTTP cache information for same-origin resources
Summary: API to expose HTTP cache information for same-origin resources
Status: RESOLVED WORKSFORME
Alias: None
Product: WHATWG
Classification: Unclassified
Component: HTML (show other bugs)
Version: unspecified
Hardware: Other other
: P3 enhancement
Target Milestone: Needs Impl Interest
Assignee: Ian 'Hixie' Hickson
QA Contact: contributor
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-01-15 20:27 UTC by François REMY
Modified: 2015-08-07 16:23 UTC (History)
5 users (show)

See Also:


Attachments

Description François REMY 2013-01-15 20:27:23 UTC
Some offline web applications need a way to detect whether a file is in cache or not. Currently, it's not possible to do so without downloading the file. Here are a few use cases where this ability would be useful:

1. Using an already cached version of the file if it's available, download the best version otherwise.
	
	// if we need a low-resolution image
	if(deviceToPixelRatio <= 1) {
		
		// if the high resolution image has already been downloaded
		if(applicationCache.isCached("./images/abc-123.2x.png")) {
			// use the high resolution image straightaway
		} else {
			// use or download a standard resolution image (faster)
		}
		
	} else {
		
		// use or download the high-resolution image
		
	}
	
2. Using an index it was already downloaded

Let's suppose you have a list of scientific documents stored locally. The user types a query in to search the content of the documents. You want to help him find the results he want by expanding his query (ie: adding synonymous of the typed words as part of the query). You can do so by querying a third-party server that will give you the results based on a dictionary <http://syn.org/word/{WORD}>).

However, the user may want to be able to use the functionality offline and download the dictionary <http://syn.org/all.json> as part of an appcache (this may result from an action done in another app using the same service which you don't know). If he does so, you want your application to use this dictionary directly and not issue a request to the server. We assume the CORS settings of the syn.org website are done so that you can access all data you need.

	if(dict) {
		task.done(dict[word]);
		
	} else if(applicationCache.isCached("http://syn.org/all.json")) {
		var xhr = ...
		xhr.open("GET", "http://syn.org/all.json", true)
		xhr.onload = function() {
			dict = xhr.response;
			task.done(dict[word]);
		}
		...
		
	} else {
		var xhr = ...
		xhr.open("GET", "http://syn.org/word/"+encodeURIComponent(word), true)
		xhr.onload = function() {
			task.done(xhr.response);
		}
		
	}

3. Evaluating the time needed to make a feature available offline.

Imagine a web application similar to Microsoft Excel. By default, the appcache will include the most basic features & function, and a bit of formatting (the rest is being done in the cloud). However, if an user want to edit graphics offline, it needs to download an API file for that. When the user if offline, you may want to know if the graphic library is available (=cached) or not in order to put the "insert graph" button in its disabled state otherwise.

Now, the user return online because he really needed the graph library. The user want to see how many content will need to be downloaded if he want to "install" the graphing library for offline use the next time. If the Graphing library depends on some APIs used by more components, and that you want to say to user how many files will need to be dowloaded in order to make the functionnality available offline, you need to know how many of those components are already cached.

You can either try to persist this yourself or rely on applicationCache.isCached(...) to get accurate results.

_____________________________
This bug is a duplicate of the HTML.Next proposal located here:
https://www.w3.org/Bugs/Public/show_bug.cgi?id=20677

It has been created to empower discussions about inclusion of the proposed method in the Live HTML Specification. I'll personally monitor both bugs and try to keep the discussion in sync (I expect most of the discussion to happen here so I'll probably post summaries to the HTMLWG if I feel it's necessary.
Comment 1 Ian 'Hixie' Hickson 2013-04-13 16:21:16 UTC
Is this specific to offline application caches? If so, the only way you could have something cached but not know it is if it's a file with a fallback resource, right?
Comment 2 FremyCompany 2013-04-13 16:45:24 UTC
No, I should probably not have included 'appcache' in the title because it also consider the browser cache. My use case is about knowing if requesting the content of a file will or not impact the network.



If an appcache is in use && the file is not in the network section of the appcache:

> return true if any of those conditions are met:
-- the file is a local file
-- the file is cached
-- the file has a cached fallback

Else:

> return true if any of those conditions are met:
-- the file is a local file
-- the file has already been downloaded during this session
-- the file has been downloaded recently, was cached, and didn't Expire yet

In all other cases, return false
Comment 3 Ian 'Hixie' Hickson 2013-04-14 07:38:10 UTC
What would you return for a file that is in the local cache but has expired, or is in the local cache but for which we will first contact the server to ask if there's a new version?
Comment 4 François REMY 2013-04-14 15:51:07 UTC
If the user is offline, the cached version will be used even if it expired, so we may want to return true. In the other case, we may trigger a download by requesting the file, so we should return false.

Another, more elegant solution, is to return an object with interface CacheStatus { url: string, exists: bool, inAppCache: bool, inAppCacheFallback: bool, inSessionCache: bool, inBrowserCache: bool, expired: bool, lastModified: Date, etag: string, loadAsync: Future<ArrayBuffer>, ... }

var cache = applicationCache.getStatusOf("myImage.png").;
if(!cache.expired || (cache.exists && cache.lastModified.isNotOlderThan(3*Date.DAY)) {
    // use cache.loadAsync and use the cached version anyway
} else {
    // use XMLHttpRequest to download the file
    // (or fallback to something else)
}
Comment 5 Ian 'Hixie' Hickson 2013-10-01 21:45:45 UTC
That would be interesting, indeed. Do we have any browser vendors interested in exposing HTTP cache data?
Comment 6 FremyCompany 2013-10-01 22:07:22 UTC
This is not exposed to the web platform; but the Windows 8.1 Web API solve my problem in the case of Windows 8 Apps:

http://msdn.microsoft.com/en-us/library/windows/apps/windows.web.http.filters.httpcachereadbehavior.aspx

I can request a file. I can only ask to get the file only if it is in cache, which enables this pattern in some way: the only unavailable information is the etag; but a server using a hash of the file content can collaborate with the client based on that only.
Comment 7 Ian 'Hixie' Hickson 2014-05-16 19:36:45 UTC
This might be something that would fit into the Service Workers work.
Comment 8 Anne 2014-05-17 11:24:26 UTC
Service workers will give us a new Cache() API, but it's unrelated to the HTTP cache. It sits above it.
Comment 9 Anne 2015-08-07 16:23:33 UTC
Cache control is being worked on as part of Fetch.