IMarks
IMarks

Reputation: 197

Service worker spreading

I have a service worker for caching images, this service worker is only registered within the frontend template but it still keeps spreading into my admin template.

This causes my forms to behave unpredictably as the validation tokens get impacted with it.

With some console.log I figured the install event is triggered before getting to the requested page but I'm unable to determine the current/next URL there.

How can I prevent the service worker to spreading to the admin panel and interfere with the pages? I just want only assets to be cached.

This is my service worker as far as that is relevant:

const PRECACHE = 'precache-v1.0.0';
const RUNTIME = 'runtime';

// A list of local resources we always want to be cached.
const PRECACHE_URLS = [
    "public",
    "media",
    "unify",
];

importScripts('./cache-polyfill.js');

// The install handler takes care of precaching the resources we always need.
self.addEventListener('install', function(event) {
    console.log('installing resources');
    event.waitUntil(
        caches.open(PRECACHE)
            //.then(cache => cache.addAll(PRECACHE_URLS))
            .then(self.skipWaiting())
    );
});

// The activate handler takes care of cleaning up old caches.
self.addEventListener('activate', function(event) {
    const currentCaches = [PRECACHE, RUNTIME];
    event.waitUntil(
        caches.keys().then(cacheNames => {
            return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));
        }).then(cachesToDelete => {
            return Promise.all(cachesToDelete.map(cacheToDelete => {
                return caches.delete(cacheToDelete);
            }));
        }).then(() => self.clients.claim())
    );
});

// The fetch handler serves responses for same-origin resources from a cache.
// If no response is found, it populates the runtime cache with the response
// from the network before returning it to the page.
self.addEventListener('fetch', event => {
    // Skip cross-origin requests, like those for Google Analytics.

    if (event.request.method === "GET") {
        if (event.request.url.indexOf(PRECACHE_URLS) > -1) {
            console.log("fetching " + event.request.url + " by the service worker");
            event.respondWith(
                caches.match(event.request).then(cachedResponse => {
                    if (cachedResponse) {
                        return cachedResponse;
                    }

                    return caches.open(RUNTIME).then(cache => {
                        return fetch(event.request).then(response => {
                            // Put a copy of the response in the runtime cache.
                            return cache.put(event.request, response.clone()).then(() => {
                                console.log('cached: ' + event.request.url);
                                return response;
                            });
                        });
                    });
                })
            );
        }
        else {
            console.log("fetching " + event.request.url + " by service worker blocked, it's not a resource");
        }
    }
    return fetch(event.request);
});

Upvotes: 1

Views: 227

Answers (1)

pate
pate

Reputation: 5253

The problem is most likely that your admin pages lie inside the SW scope. This means that your SW controls eg. everything in / and your admin pages are located in /admin/ or something.

You can prevent the behaviour by checking the fetch requests your SW is intercepting. Something like:

if (event.request.url.match('^.*(\/admin\/).*$')) {
    return false;
}

This should be the first thing in the SW's fetch listener. It checks whether it received a request for something from the admin pages and then cancels out if it did. Otherwise, it continues normally.

Upvotes: 2

Related Questions