PikoPong
  • Web Dev
  • Hack
  • Database
  • Big Data
  • AWS
  • Linux
No Result
View All Result
PikoPong
  • Web Dev
  • Hack
  • Database
  • Big Data
  • AWS
  • Linux
No Result
View All Result
PikoPong
No Result
View All Result
Home Web Dev

The Cache API: A quick guide

May 23, 2020
in Web Dev
274 18
Read files in JavaScript


Learn how to use the Cache API to make your application data available offline.

Oct 3, 2017
• Updated Apr 27, 2020


Pete LePage

The Cache API is a system for storing and retrieving network
requests and their corresponding responses. These might be regular requests
and responses created in the course of running your application, or they could
be created solely for the purpose of storing data for later use.

The Cache API was created to enable service workers to cache network requests
so that they can provide fast responses, regardless of network speed or
availablity. However, the API can also be used as a general storage mechanism.

Where is it available? #

The Cache API is available in all modern browsers. It is
exposed via the global caches property, so you can test for the presence of
the API with a simple feature detection:

const cacheAvailable = 'caches' in self;

The Cache API can be accessed from a window, iframe, worker, or service worker.

What can be stored #

The caches only store pairs of Request and
Response objects, representing HTTP requests and responses,
respectively. However, the requests and responses can contain any kind of data
that can be transferred over HTTP.

How much can be stored? #

In short, a lot, at least a couple of hundred megabytes, and potentially
hundreds of gigabytes or more. Browser implementations vary, but the amount
of storage available is usually based on the amount of storage available on
the device.

Creating and opening a cache #

To open a cache, use the caches.open(name) method, passing the name of the
cache as the single parameter. If the named cache does not exist, it is
created. This method returns a Promise that resolves with the Cache object.

const cache = await caches.open('my-cache');

Adding to a cache #

There are three ways to add an item to a cache – add, addAll, and put.
All three methods return a Promise.

cache.add #

First, there is cache.add(). It takes one parameter, either a Request
or a URL (string). It makes a request to the network and stores the response
in the cache. If the
fetch fails, or if the status code of the response is not in the 200 range,
then nothing is stored and the Promise rejects. Note that cross-origin
requests not in CORS mode cannot be stored because they return a status of
0. Such requests can only be stored with put.


cache.add(new Request('/data.json'));


cache.add('/data.json');

cache.addAll #

Next, there is cache.addAll(). It works similarly to add(), but takes an
array of Request objects or URLs (strings). This works similarly to
calling cache.add for each individual request, except that the Promise
rejects if any single request is not cached.

const urls = ['/weather/today.json', '/weather/tomorrow.json'];
cache.addAll(urls);

In each of these cases, a new entry overwrites any matching existing entry.
This uses the same matching rules described in the section on
retrieving.

cache.put #

Finally, there is cache.put(), which allows you to store either a response
from the network, or create and store your own Response. It takes two
parameters. The first can either be a Request object or a URL (string).
The second must be a Response, either from the network, or generated by your
code.


cache.put('/data.json');


cache.put('/test.json', new Response('{"foo": "bar"}'));


cache.put('https://example.com/data.json');

The put() method is more permissive than either add() or addAll(), and
will allow you to store non-CORS responses, or other responses where the status
code of the response is not in the 200 range. It will overwrite any previous
responses for the same request.

Creating Request objects #

Create the Request object using a URL for the thing being stored:

const request = new Request('/my-data-store/item-id');

Working with Response objects #

The Response object constructor accepts many types of data, including
Blobs, ArrayBuffers, FormData objects, and strings.

const imageBlob = new Blob([data], {type: 'image/jpeg'});
const imageResponse = new Response(imageBlob);
const stringResponse = new Response('Hello world');

You can set the MIME type of a Response by setting the appropriate header.

  const options = {
headers: {
'Content-Type': 'application/json'
}
}
const jsonResponse = new Response('{}', options);

If you have retrieved a Response and wish to access its body, there are
several helper methods you can use. Each returns a Promise that resolves
with a value of a different type.

Method Description
arrayBuffer Returns an ArrayBuffer containing the body, serialized to
bytes.
blob Returns a Blob. If the Response was created
with a Blob then this new Blob has the same
type. Otherwise, the Content-Type of the
Response is used.
text Interprets the bytes of the body as a UTF-8 encoded string.
json Interprets the bytes of the body as a UTF-8 encoded string, then tries
to parse it as JSON. Returns the resulting object, or throws a
TypeError if the string cannot be parsed as JSON.
formData Interprets the bytes of the body as an HTML form, encoded either as
multipart/form-data or
application/x-www-form-urlencoded. Returns a
FormData
object, or throws a TypeError if the data cannot be parsed.
body Returns a ReadableStream
for the body data.

For example

const response = new Response('Hello world');
const buffer = await response.arrayBuffer();
console.log(new Uint8Array(buffer));

Retrieving from a cache #

To find an item in a cache, you can use the match method.

const response = await cache.match(request);
console.log(request, response);

If request is a string the browser converts it to a Request by calling
new Request(request). The function returns a Promise that resolves to
a Response if a matching entry is found, or undefined otherwise.

To determine if two Requests match, the browser uses more than just the URL. Two
requests are considered different if they have different query strings,
Vary headers, or HTTP methods (GET, POST, PUT, etc.).

You can ignore some or all of these things by passing an options object as a
second parameter.

const options = {
ignoreSearch: true,
ignoreMethod: true,
ignoreVary: true
};

const response = await cache.match(request, options);

If more than one cached request matches then the one that was created first is
returned. If you want to retrieve all matching responses, you can use
cache.matchAll().

const options = {
ignoreSearch: true,
ignoreMethod: true,
ignoreVary: true
};

const responses = await cache.matchAll(request, options);
console.log(`There are ${responses.length} matching responses.`);

As a shortcut you can search over all caches at once by using caches.match()
instead of calling cache.match() for each cache.

Searching #

The Cache API does not provide a way to search for requests or responses
except for matching entries against a Response object. However, you can
implement your own search using filtering or by creating an index.

Filtering #

One way to implement your own search is to iterate over all entries and
filter down to the ones that you want. Let’s say that you want to find all
items that have URLs ending with .png.

async function findImages() {
const cacheNames = await caches.keys();
const result = [];

for (const name of cacheNames) {
const cache = await caches.open(name);


for (const request of await cache.keys()) {
if (request.url.endsWith('.png')) {
result.push(await cache.match(request));
}
}
}

return result;
}

This way you can use any property of the Request and Response objects to
filter the entries. Note that this is slow if you search over large sets of
data.

Creating an index #

The other way to implement your own search is to maintain a separate index of
entries that can be searched and store the index in IndexedDB. Since this is the kind of
operation that IndexedDB was designed for it has much better performance with
large numbers of entries.

If you store the URL of the Request alongside the searchable properties
then you can easily retrieve the correct cache entry after doing the search.

Deleting an item #

To delete an item from a cache:

cache.delete(request);

Where request can be a Request or a URL string. This method also takes the
same options object as cache.match, which allows you to delete multiple
Request/Response pairs for the same URL.

cache.delete('/example/file.txt', {ignoreVary: true, ignoreSearch: true});

Deleting a cache #

To delete a cache, call caches.delete(name). This function returns a
Promise that resolves to true if the cache existed and was deleted, or
false otherwise.

Thanks #

Thanks to Mat Scales who wrote the original version of this article, which
first appeared on WebFundamentals.

Last updated: Apr 27, 2020



Improve article



Source link

Share219Tweet137Share55Pin49

Related Posts

On Auto-Generated Atomic CSS | CSS-Tricks
Web Dev

On Auto-Generated Atomic CSS | CSS-Tricks

Robin Weser’s “The Shorthand-Longhand Problem in Atomic CSS” in an interesting journey through a tricky problem. The point is...

January 15, 2021
How to Add Commas Between a List of Items Dynamically with CSS
Web Dev

3 Approaches to Integrate React with Custom Elements

In my role as a web developer who sits at the intersection of design and code, I am drawn...

January 15, 2021
Community Resources, Weekly Newsletter, And Boosting Skills Online — Smashing Magazine
Web Dev

Smashing Workshops & Audits — Smashing Magazine

About The AuthorJuggling between three languages on a daily basis, Iris is known for her love of linguistics, arts,...

January 15, 2021
4 Lessons Web App Designers Can Learn From Google — Smashing Magazine
Web Dev

The Report — Smashing Magazine

About The AuthorSuzanne Scacca is a former WordPress implementer, trainer and agency manager who now works as a freelance...

January 15, 2021
Next Post
Setting TypeScript For Modern React Projects Using Webpack And Babel — Smashing Magazine

Setting TypeScript For Modern React Projects Using Webpack And Babel — Smashing Magazine

From 48k lines of code to 10—the story of GitHub’s JavaScript SDK

From 48k lines of code to 10—the story of GitHub's JavaScript SDK

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recommended

What Is TypeScript? — Smashing Magazine

October 20, 2020
Hide Scrollbars During an Animation

Hide Scrollbars During an Animation

June 24, 2020
Simulating Drop Shadows with the CSS Paint API

Simulating Drop Shadows with the CSS Paint API

December 29, 2020
Accessibility In Chrome DevTools — Smashing Magazine

Accessibility In Chrome DevTools — Smashing Magazine

September 1, 2020

Categories

  • AWS
  • Big Data
  • Database
  • DevOps
  • IoT
  • Linux
  • Web Dev
No Result
View All Result
  • Web Dev
  • Hack
  • Database
  • Big Data
  • AWS
  • Linux

Welcome Back!

Login to your account below

Forgotten Password?

Create New Account!

Fill the forms bellow to register

All fields are required. Log In

Retrieve your password

Please enter your username or email address to reset your password.

Log In