缓存
interface provides a storage mechanism for
/
Request
object pairs that are cached, for example as part of the
响应
ServiceWorker
life cycle. Note that the
缓存
interface is exposed to windowed scopes as well as workers. You don't have to use it in conjunction with service workers, even though it is defined in the service worker spec.
An origin can have multiple, named
缓存
objects. You are responsible for implementing how your script (e.g. in a
ServiceWorker
) handles
缓存
updates. Items in a
缓存
do not get updated unless explicitly requested; they don’t expire unless deleted. Use
CacheStorage.open()
to open a specific named
缓存
object and then call any of the
缓存
methods to maintain the
缓存
.
You are also responsible for periodically purging cache entries. Each browser has a hard limit on the amount of cache storage that a given origin can use. Cache quota usage estimates are available via the
StorageEstimate
API. The browser does its best to manage disk space, but it may delete the Cache storage for an origin. The browser will generally delete all of the data for an origin or none of the data for an origin. Make sure to version caches by name and use the caches only from the version of the script that they can safely operate on. See
Deleting old caches
了解更多信息。
注意 : The key matching algorithm depends on the VARY header in the value. So matching a new key requires looking at both key and value for entries in the Cache.
注意: The caching API doesn't honor HTTP caching headers.
Cache.match(request, options)
Promise
that resolves to the response associated with the first matching request in the
缓存
对象。
Cache.matchAll(request, options)
Promise
that resolves to an array of all matching requests in the
缓存
对象。
Cache.add(request)
fetch()
, then using
put()
to add the results to the cache.
Cache.addAll(requests)
Takes an array of URLs, retrieves them, and adds the resulting response objects to the given cache.
Cache.put(request, response)
Takes both a request and its response and adds it to the given cache.
Cache.delete(request, options)
缓存
entry whose key is the request, returning a
Promise
that resolves to
true
if a matching
缓存
entry is found and deleted. If no
缓存
entry is found, the promise resolves to
false
.
Cache.keys(request, options)
Promise
that resolves to an array of
缓存
键。
This code snippet is from the
service worker selective caching sample
. (see
selective caching live
) The code uses
CacheStorage.open()
to open any
缓存
objects with a
Content-Type
header that starts with
font/
.
The code then uses
Cache.match()
to see if there's already a matching font in the cache, and if so, returns it. If there isn't a matching font, the code fetches the font from the network and uses
Cache.put()
to cache the fetched resource.
The code handles exceptions thrown from the
fetch()
operation. Note that an HTTP error response (e.g., 404) will not trigger an exception. It will return a normal response object that has the appropriate error code.
The code snippet also shows a best practice for versioning caches used by the service worker. Though there's only one cache in this example, the same approach can be used for multiple caches. It maps a shorthand identifier for a cache to a specific, versioned cache name. The code also deletes all caches that aren't named in
CURRENT_CACHES
.
In the code example,
caches
是特性在
ServiceWorkerGlobalScope
. It holds the
CacheStorage
object, by which it can access the
CacheStorage
interface. This is an implementation of the
WindowOrWorkerGlobalScope
混合。
chrome://inspect/#service-workers
and click on the "inspect" link below the registered service worker to view logging statements for the various actions the
service-worker.js
script is performing.
var CACHE_VERSION = 1;
var CURRENT_CACHES = {
font: 'font-cache-v' + CACHE_VERSION
};
self.addEventListener('activate', function(event) {
// Delete all caches that aren't named in CURRENT_CACHES.
// While there is only one cache in this example, the same logic will handle the case where
// there are multiple versioned caches.
var expectedCacheNamesSet = new Set(Object.values(CURRENT_CACHES));
event.waitUntil(
caches.keys().then(function(cacheNames) {
return Promise.all(
cacheNames.map(function(cacheName) {
if (!expectedCacheNamesSet.has(cacheName)) {
// If this cache name isn't present in the set of "expected" cache names, then delete it.
console.log('Deleting out of date cache:', cacheName);
return caches.delete(cacheName);
}
})
);
})
);
});
self.addEventListener('fetch', function(event) {
console.log('Handling fetch event for', event.request.url);
event.respondWith(
caches.open(CURRENT_CACHES.font).then(function(cache) {
return cache.match(event.request).then(function(response) {
if (response) {
// If there is an entry in the cache for event.request, then response will be defined
// and we can just return it. Note that in this example, only font resources are cached.
console.log(' Found response in cache:', response);
return response;
}
// Otherwise, if there is no entry in the cache for event.request, response will be
// undefined, and we need to fetch() the resource.
console.log(' No response for %s found in cache. About to fetch ' +
'from network...', event.request.url);
// We call .clone() on the request since we might use it in a call to cache.put() later on.
// Both fetch() and cache.put() "consume" the request, so we need to make a copy.
// (see ../API/Request/clone)
return fetch(event.request.clone()).then(function(response) {
console.log(' Response for %s from network is: %O',
event.request.url, response);
if (response.status < 400 &&
response.headers.has('content-type') &&
response.headers.get('content-type').match(/^font\//i)) {
// This avoids caching responses that we know are errors (i.e. HTTP status code of 4xx or 5xx).
// We also only want to cache responses that correspond to fonts,
// i.e. have a Content-Type response header that starts with "font/".
// Note that for opaque filtered responses (https://fetch.spec.whatwg.org/#concept-filtered-response-opaque)
// we can't access to the response headers, so this check will always fail and the font won't be cached.
// All of the Google Web Fonts are served off of a domain that supports CORS, so that isn't an issue here.
// It is something to keep in mind if you're attempting to cache other resources from a cross-origin
// domain that doesn't support CORS, though!
// We call .clone() on the response to save a copy of it to the cache. By doing so, we get to keep
// the original response object which we will return back to the controlled page.
// (see ../API/Request/clone)
console.log(' Caching the response to', event.request.url);
cache.put(event.request, response.clone());
} else {
console.log(' Not caching the response to', event.request.url);
}
// Return the original response object, which will be used to fulfill the resource request.
return response;
});
}).catch(function(error) {
// This catch() will handle exceptions that arise from the match() or fetch() operations.
// Note that a HTTP error response (e.g. 404) will NOT trigger an exception.
// It will return a normal response object that has the appropriate error code set.
console.error(' Error in fetch handler:', error);
throw error;
});
})
);
});
抓取 API
requires
Set-Cookie
headers to be stripped before returning a
响应
对象从
fetch()
. So a
响应
stored in a Cache won't contain headers.
| 规范 | 状态 | 注释 |
|---|---|---|
|
服务工作者
The definition of 'Cache' in that specification. |
工作草案 | 初始定义。 |
| 桌面 | 移动 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
缓存
|
Chrome
43
注意事项
|
Edge ≤18 |
Firefox
39
注意事项
|
IE 不支持 No |
Opera
30
注意事项
|
Safari 11 |
WebView Android
43
注意事项
|
Chrome Android
43
注意事项
|
Firefox Android 39 |
Opera Android
30
注意事项
|
Safari iOS 11 |
Samsung Internet Android
4.0
注意事项
|
add
|
Chrome
44
注意事项
|
Edge 16 |
Firefox
39
注意事项
|
IE 不支持 No |
Opera
31
注意事项
|
Safari 11 |
WebView Android
44
注意事项
|
Chrome Android
44
注意事项
|
Firefox Android 39 |
Opera Android
32
注意事项
|
Safari iOS 11 |
Samsung Internet Android
4.0
注意事项
|
addAll
|
Chrome
46
注意事项
|
Edge 16 |
Firefox
39
注意事项
|
IE 不支持 No |
Opera
33
注意事项
|
Safari 11 |
WebView Android
46
注意事项
|
Chrome Android
46
注意事项
|
Firefox Android 39 |
Opera Android
33
注意事项
|
Safari iOS 11 |
Samsung Internet Android
5.0
注意事项
|
delete
|
Chrome 43 | Edge 16 |
Firefox
39
注意事项
|
IE 不支持 No | Opera 30 | Safari 11 | WebView Android 43 | Chrome Android 43 | Firefox Android 39 | Opera Android 30 | Safari iOS 11 | Samsung Internet Android 4.0 |
keys
|
Chrome 43 | Edge 16 |
Firefox
39
注意事项
|
IE 不支持 No | Opera 30 | Safari 11 | WebView Android 43 | Chrome Android 43 | Firefox Android 39 | Opera Android 30 | Safari iOS 11 | Samsung Internet Android 4.0 |
match
|
Chrome 43 | Edge 16 |
Firefox
39
注意事项
|
IE 不支持 No | Opera 30 | Safari 11 | WebView Android 43 | Chrome Android 43 | Firefox Android 39 | Opera Android 30 | Safari iOS 11 | Samsung Internet Android 4.0 |
matchAll
|
Chrome 47 | Edge 16 |
Firefox
39
注意事项
|
IE 不支持 No |
Opera
34
注意事项
|
Safari 11 | WebView Android 47 | Chrome Android 47 | Firefox Android 39 | Opera Android 34 | Safari iOS 11 | Samsung Internet Android 5.0 |
put
|
Chrome
43
注意事项
|
Edge 16 |
Firefox
39
注意事项
|
IE 不支持 No |
Opera
30
注意事项
|
Safari 11 |
WebView Android
43
注意事项
|
Chrome Android
43
注意事项
|
Firefox Android 39 |
Opera Android
30
注意事项
|
Safari iOS 11 |
Samsung Internet Android
4.0
注意事项
|
完整支持
不支持
实验。期望将来行为有所改变。
见实现注意事项。
缓存
CacheStorage
Client
Clients
ExtendableEvent
FetchEvent
InstallEvent
Navigator.serviceWorker
NotificationEvent
PeriodicSyncEvent
PeriodicSyncManager
PeriodicSyncRegistration
ServiceWorker
ServiceWorkerContainer
ServiceWorkerGlobalScope
ServiceWorkerRegistration
SyncEvent
SyncManager
SyncRegistration
WindowClient