Search code examples
javascriptbrowser-cachecacheapi

Displaying cached image via Cache API


I'm trying to use the Cache API to store large files (one being 500MB) for offline use. I'm able to create/open the cache, fetch the image URL from AWS S3, and put it into the cache:

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

let url = 'https://[mybucket].s3.amazonaws.com/example.png';

await fetch(url).then( async (response) => {
  if (!response.ok) {
    throw new TypeError("Bad response status");
  }

  return cache.put(url, response);
});

This appears properly in the inspector with (what I think) are the correct CORS/content size responses:

Cache storage

I'm also able to find it in the cache, however instead of searching for the full S3 url it seems to only store it with /example.png as the match:

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

let img = await cache.match('/example.png', options);

This returns a ReadableStream successfully, but I don't know where to go next.

I am hoping to default to loading from the cache since the file sizes can get quite large.


Solution

  • Checking the documentation for Cache.match(), what you're getting in response should be - well, a Response! So, from there, you can use Response.blob() and pass that into URL.createObjectURL(), which you can make the src of your image.

    That was a mouthful, so here it is in code.

    // Get the cached item...
    const options = {
      ignoreSearch: true,
      ignoreMethod: true,
      ignoreVary: true
    };
    
    let img = await cache.match('/example.png', options);
    
    // Handle the possibility of undefined
    if(img === undefined) { return false; }
    
    // Convert the image data to a blob...
    let blob = img.blob();
    
    // Assuming imgElement is our image element...
    imgElement.src = URL.createObjectURL(blob);
    
    // And finish it all off nicely.
    return true;