Search code examples
service-workerpreloadjscacheapi

PreloadJS and Service Worker


I am trying to use service worker with PreloadJS. I have cached the images required and then loading them using the caches.match() function.

When I try to load the image with jquery it works fine, but on loading with preloadJS it gives the following error

The FetchEvent for "someurl" resulted in a network error response: an "opaque" response was used for a request whose type is not no-cors

Although if I load any other image that isn't cached, PreloadJS loads that image properly. The problem is occuring only when I use caches.match.

What might be the reason for this ?

Load Image using preloadjs

var preload = new createjs.LoadQueue({ crossOrigin: "Anonymous" });

function loadImageUsingPreload() {

  preload.on('complete', completed);

  preload.loadFile({ id: 'someid', src: 'someurl', crossOrigin: true })

};

function completed() {
  var image = preload.getResult("shd");
  document.body.append(image);
};

Load Image using jquery

function loadImageUsingJquery() {
  jQuery("#image").attr('src', 'someurl');
};

Service Worker fetch event

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request).then(function(response) {

      if (!response) {
        console.log('fetching...' + event.request.url);
        return fetch(event.request);
      };
      console.log("response", response);
      return response;
    }));
});

The response object when I load using PreloadJS or jQuery:

Response {type: "opaque", url: "", redirected: false, status: 0, ok: false, …}


Solution

  • Found out the mistake ,

    Actually during cache.put I was modifying the request object's mode to 'no-cors' if the origin were not the same.

    Now during a fetch event, the event's request object had property 'cors' because it was a cross-origin request.

    This difference of value of mode was causing the fetch error.

    Service worker install event:

    var request = new Request(value);
    var url = new URL(request.url);
    
    if (url.origin != location.origin) {
        request = new Request(value, { mode: 'no-cors' });
    }
    
    return fetch(request).then(function(response) {
        var cachedCopy = response.clone();
        return cache.put(request, cachedCopy);
    });
    

    I changed it to :

    var request = new Request(value);
    var url = new URL(request.url);
    
    return fetch(request).then(function(response) {
        var cachedCopy = response.clone();
        return cache.put(request, cachedCopy);
    });
    

    I have to use the first method for saving cdn's because second method is not working for them and vice-versa for my images hosted on cloudfront .

    I will post the reason when I find why this is happening.