Service Worker fetch request from cache so page is not getting updated from new data

旧时模样 提交于 2020-01-03 05:03:11

问题


I am trying to implement the service worker in my AngularJS project for the purpose that if the server(nginx in my case) is restarted then offline page must be displayed for that period but I stuck in the other case.

I have a page where I list the items using GET request, it's fetching response from the server (for the 1 st time), response data being stored in cache BUT my page is updating within regular interval so using this technique the new data are not displaying immediately.

What is wrong in this approach, kindly suggest the better way.

folder structure

.
├── app
├── assets
├── favicon.ico
├── index.html
├── libs
├── offline.html
└── sw.js

below is the code of my service worker file

sw.js

'use strict';

let appCaches = [{
    name: 'static',
    urls: [
        '/app/',
        '/'
    ]
}, {
    name: 'offline',
    urls: [
        '/offline.html'
    ]
}];

let cacheNames = appCaches.map((cache) => cache.name);

self.addEventListener("install", (event) => {
    // console.log('installing');
    event.waitUntil(
        caches.keys()
        .then((keys) => {
            return Promise.all(appCaches.map((appCache) => {
                console.log(`cache Name:: ${appCache.name}`);
                console.log(`keys:: ${keys}`);
                if (keys.indexOf(appCache.name) === -1) {
                    caches.open(appCache.name).then((cache) => {
                        console.log(`caching ${appCache.name}`);
                        return cache.addAll(appCache.urls);
                    });
                } else {
                    console.log(`found ${appCache.name}`);
                    return Promise.resolve(true);
                }
            })).then(function() {
                // At this point everything has been cached
                return self.skipWaiting();
            });
        }));
});


//Adding `activate` event listener
self.addEventListener('activate', (event) => {
    // console.info('Event: Activate');
    //Remove old and unwanted caches
    event.waitUntil(
        caches.keys().then((keys) => {
            return Promise.all(keys.map((key) => {
                console.log(`activation checking key ${key}`);
                if (cacheNames.indexOf(key) === -1) {
                    console.log(`deleting ${key}`);
                    return caches.delete(key);
                }
            }));
        })
    );
});

//-------------------------------------------------------------------
function addToCache(cacheKey, request, response) {
    console.log("addToCache", arguments);
    if (response.ok) {
        var copy = response.clone();
        caches.open(cacheKey).then((cache) => {
            cache.put(request, copy);
        });
        return response;
    }
}

function fetchFromCache(event) {
    console.log("fetchFromCache", arguments);
    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;
    });
}

function offlineResponse(resourceType) {
    console.log("%c offlineResponse::resourceType::" + resourceType, 'color:green');
    if (resourceType === 'content') {
        return caches.match('/offline.html');
    }
    return undefined;
}

self.addEventListener('fetch', (event) => {
    var request = event.request;
    var url = new URL(request.url);
    console.log("%curl=>" + url, 'color:red');
    var acceptHeader = request.headers.get('Accept');
    var resourceType = 'static';
    var cacheKey;

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

    // {String} [static|image|content]
    cacheKey = resourceType;

    if (request.method !== 'GET') {
        return;
    } else {
        console.log("resourceType=>", cacheKey);
        if (resourceType === 'content') {
            // Use a network-first strategy.
            console.info("Use a network-first strategy.");
            event.respondWith(
                fetch(request)
                .then((response) => addToCache(cacheKey, request, response))
                .catch(() => fetchFromCache(event))
                .catch(() => offlineResponse(resourceType))
            );
        } else {
            // Use a cache-first strategy.
            console.info("Use a cache-first strategy.");
            event.respondWith(
                fetchFromCache(event)
                .catch(() => fetch(request))
                .then((response) => addToCache(cacheKey, request, response))
                .catch(() => offlineResponse(resourceType))
            );
        }
    }
});

回答1:


Your key for the resource in cache is request (Since you are using cache.put(request, copy) in addToCache function), but you are retrieving it using url (e.g /offline.html in offlineResponse function). You should match with request in cache.



来源:https://stackoverflow.com/questions/45620581/service-worker-fetch-request-from-cache-so-page-is-not-getting-updated-from-new

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!