preface

IndexedDB, localStorage, sessionStorage, File System API, applicationCache, etc. What are the advantages over other storage mechanisms?

Introduction to the

The Cache API is a storage mechanism enabled by the PWA ServiceWorker to enable data requests to go offline. Similar to applicationCache, it provides very fine-grained storage control, with content completely controlled by scripts. Fetch is often used with serviceworker, and different headers of the same URL can store multiple responses. Cross-domain sharing is not provided and is completely isolated from HTTP caching.

Differences with other storage mechanisms:

  • The Cache API is an asynchronous storage mode, which must be used in ServiceWorker.
  • Cache API stores Requst as key and Response as value. Asynchronous IndexDB is based on structured clone storage, which cannot store streaming data. Conversion costs are too high, which increases memory usage and affects speed.

CacheStorage method

CacheStorage is an interface for Cache object storage. You can obtain it in either of the following ways:

ServiceWorkerGlobalScope.caches

Window.caches
Copy the code

Note: This parameter can be used only in HTTPS environment.

The following are in the ServiceWork GlobalScope environment.

open

Grammar:

// cachs is a read-only global variable for the CacheStorage instance
caches.open(cacheName).then(cache= > {
  // Handle operations related to open cache instances
});
Copy the code

Open (or create) the Cache instance of cacheName if it does not exist.

Return Promise, resolve as Cache instance.

delete

Grammar:

caches.delete(cacheName).then(boolean= > {
  // true: The cache is discovered and deleted
});
Copy the code

Search for Cache objects matching cacheName. Delete the Cache object and return a Promise that resolve is true. If no Cache object is found, false is returned.

keys

Grammar:

caches.keys().then(keyList= > {
  // Perform operations on keyList
});
Copy the code

Return to the Promise. An array containing all Cache object name strings under CacheStorage.

has

Grammar:

caches.has(cacheName).then(boolean= > {
  // true: The cacheName cache exists
});
Copy the code

Return a Promise object with the Boolean value true for resolve if the cache exists and false otherwise.

match

Grammar:

caches.match(request[, options]).then(response= > {
  / / response operations
  // Resolve returns undefined if no match is found
});
Copy the code

Parameters:

Request: indicates the request to be matched. It can be a Request object or a URL string.

Options :(optional) optional. Used to control how the matching operation is performed.

  • IgnoreSearch: Boolean, false. Whether to ignore url query parameters during matching.
  • IgnoreMethod: Boolean, false. Request method (GET/HEAD) matches are ignored when true.
  • IgnoreVary: Boolean, false. Ignore the Vary header match when true. (What is Vary?)
  • CacheName: String. Represents the cache name to search for. If this parameter is not specified, the system searches globally. If the first object is found, the system returns immediately.

The Cache method

Cache is the implementation of CacheStorage. It stores Request as a key and Response as a value. You can use cachestorage. open(cacheName) to open the Cache.

After Cache data is generated, it always exists. You need to use scripts to modify or delete Cache data.

Note: Cache. The add/Cache. Put/Cache addAll only on request method to GET under the condition of use. The cache with the same request key will be overwritten by the three methods.

put

Request and Response are added to the cache with the specified request and response.

The status of Response can be of any type.

Grammar:

cache.put(request, response).then(() = > {
  // Add request/response key-value pairs to cache
});
Copy the code

Parameters:

  • Request: Request that you want to add.
  • Response: You want to add a response that matches the Request.

TypeError: Request method POST is unsupported TypeError: Request method POST is unsupported

delete

Delete the cache matching the request key. Resolve (true)

Grammar:

cache.delete(request,{options}).then(boolean= > {
  // true: Your cache has been deleted
});
Copy the code

Parameters:

Request: request for deletion. Options :(optional) controls how delete search keys are matched (same as match method).

  • IgnoreSearch: Boolean, false. Whether to ignore url query parameters during matching.
  • IgnoreMethod: Boolean, false. Request method (GET/HEAD) matches are ignored when true.
  • IgnoreVary: Boolean, false. Ignore the Vary header match when true. (What is Vary?)

add

Given the request parameter, a response is automatically requested and filled into the cache object. Fetch + cache.put.

Note: Opaque response status cannot be added through add. Reject is returned.

Grammar:

cache.add(request).then(() = > {
  // Request has been added to cache
});
Copy the code

addAll

An array of requests as cache. add.

Note: Cache caching is completed only if all requests were successful.

Grammar:

cache.addAll(requests[]).then(() = > {
  // All requests are added to cache.
});
Copy the code

match

Return the first cache matching the request key.

Note: Resolve is returned even if no match is found, but with the value undefined.

Grammar:

cache.match(request, {options}).then(response= > {
  // Do something with response
});
Copy the code

Parameters:

Request: requests for matching requests. Options :(optional) controls how the search key matches (same as the match method).

  • IgnoreSearch: Boolean, false. Whether to ignore url query parameters during matching.
  • IgnoreMethod: Boolean, false. Request method (GET/HEAD) matches are ignored when true.
  • IgnoreVary: Boolean, false. Ignore the Vary header match when true. (What is Vary?)

matchAll

Function as cache. match, the difference being that cache. match returns matching responses[0] while cache. matchAll returns an array of all matching responses.

Grammar:

cache.matchAll(request,{options}).then(responses= > {
  // Do some processing with the responses array
});
Copy the code

Parameters:

Request: requests for matching requests. Options :(optional) controls how the search key matches (same as the match method).

  • IgnoreSearch: Boolean, false. Whether to ignore url query parameters during matching.
  • IgnoreMethod: Boolean, false. Request method (GET/HEAD) matches are ignored when true.
  • IgnoreVary: Boolean, false. Ignore the Vary header match when true. (What is Vary?)

keys

Returns all keys in the current cache instance.

Note: Requests with the same URL but different headers can be returned if they have a VARY header in their response header.

Grammar:

cache.keys(request,{options}).then(keys= > {
  // Do some processing for requests
});
Copy the code

Parameters:

Request :(optional) if a request key is specified, the corresponding request is returned. Options :(optional) controls how the search key matches (same as the match method).

  • IgnoreSearch: Boolean, false. Whether to ignore url query parameters during matching.
  • IgnoreMethod: Boolean, false. Request method (GET/HEAD) matches are ignored when true.
  • IgnoreVary: Boolean, false. Ignore the Vary header match when true. (What is Vary?)

The debug view

You can view it using Chrome’s DevTools.

Application → Cache → Cache Storage

In the Cache Storage, the cacheName Cache is created as caches. Open. In the list on the right, the Request key is added by put/ Add /addAll. Click to view the relevant request and Response below.

Cache space issues

There are three offline storage modes on the Web:

  • Temporary
  • Persistent
  • Unlimited

The Cache type is Temporary. Temporary storage is Temporary storage that can be used by any Web application without prior quota requests or user prompts, but stored data can be deleted by the browser at any time (automatically cleaned up if it takes up too much space). This is analogous to the/TMP directory of the file system.

A new experimental API can be used in Chrome and Opera to request persistent access to the device:

navigator.storage.persist().then(isGranted= > {
	// true: authorization
})
Copy the code

Offline space of each browser:

  • Chrome <6% of free space
  • Firefox <10% of free space
  • Safari <50MB
  • IE10 <250MB
  • Edge Depenent on volume size

Overflow handling strategy:

  • Chrome LRU once Chrome runs out of sapce
  • Firefox LRU if the whole disk gets full
  • Safari No eviction
  • Edge No eviction

The actual data can be viewed through the Quota Management API.

Q&A

The cross-domain cache

For cross-domain cache, the access-Control-Allow-Origin header must be enabled for cross-domain resources, and the Request mode must be set to CORS.

const req = new Request("https://cross.com", { mode: "cors" });

fetch(req).then(response= > {
  caches.open("cacheName").then(cache= > {
    cache.put(req, res);
  });
});
Copy the code

If the Access-Control-allow-Origin header is not enabled for the cross-domain resource, you need to set the mode to no-cors. However, opaque response with status 0 in response will result, as described later.

POST the cache

Since the specification in Cache states that only GET requests can be stored, what if you want to Cache POST requests?

Two ways are suggested:

  1. Serialize the Response, or extract the actual data and store it in IndexDB. When the FETCH event is monitored, match IndexDB to find the Response and generate the Response instance.
  2. For some special POST requests, for example, the contents are all solidified parameters, which usually do not change, and there is a unique flag in the URL. When such special POST is monitored in the FETCH, it can be converted into a GET Request as the cache key. After the Response is received, the Response of POST is stored as the value of the transformed GET key, which can be realized.

Opaque Opaque response cache

Opaque response resources whose response status is 0 can also be stored in the cache, but it is not recommended. Because the response status is 0, it cannot confirm whether the resource is complete and correct. After being cached, the length of the resource cannot be viewed in the cache, which may cause some storage problems.

And all of a sudden, the Cache Storage becomes 10.3MB.But the opaque response is only a few kilobytes, but it’s several megabytes in the cache.

To prevent security problems, the Chrome layer fills all opaque requests with a few MB to ensure security.

For opaque requests, you are advised to:

  • The opaque state is not cached.
  • Add a cache to the Opaque state classAccess-Control-Allow-OriginHeader to achieve state transparency.

Browser compatibility