1

I am in the process of turning one of our websites into a PWA. It has a lot of images from S3 that fail with the following console warning:

The FetchEvent for "[image url]" resulted in a network error response: an object that was not a Response was passed to respondWith().

Here's the SW code:

self.addEventListener('fetch', event => {

  function onFetch (event) {
    // Determine type of asset
    var request = event.request,
        acceptHeader = request.headers.get('Accept'),
        resourceType = 'static';

    if(acceptHeader.indexOf('text/html') !== -1) {
      resourceType = 'content';
    } else if(acceptHeader.indexOf('image') !== -1) {
      resourceType = 'image';
    }

    // Network first for HTML and images
    if(resourceType === 'content' || resourceType === 'image') {
      event.respondWith(fetch(request)
        .then(response => addToCache(request, response)) // read through caching
        .catch(() => fetchFromCache(event))
        .catch(() => offlineResponse(resourceType))
      )
    }
  }

  onFetch(event);

});

function addToCache(request, response) {

  if(response.ok) { // only 200s
    var copy = response.clone(); // Because responses can only be used once
    caches.open(cacheName)
      .then(cache => {
        cache.put(request, copy);
      });

    return response;
  }

}

function fetchFromCache (event) {

  return caches.match(event.request)
    .then(response => {
      if(!response) {
        // A synchronous error that will kick off the catch handler
        throw Error('${event.request.url} not found in cache');
      }
    return response;
  });

}

This only happens with images from S3, all others work as expected. Anyone know what's going on?

Derek Johnson
  • 285
  • 6
  • 24

1 Answers1

4

My guess is that your image responses from S3 are opaque. (See: What limitations apply to opaque responses?)

If you enable CORS in S3, and add the crossorigin attribute to your <img> tags, then your responses should all be CORS-enabled.

Alternatively, you can work around the fact that you're getting opaque responses by not checking the value of response.ok in your addToCache() function—it'll always be false for opaque responses. This means that you might end up adding a 4xx or 5xx error response to the cache instead of a valid image response, but that's the risk you run when caching opaque responses.

Community
  • 1
  • 1
Jeff Posnick
  • 53,580
  • 14
  • 141
  • 167