Service Worker从缓存中获取请求,因此页面无法从新数据

时间:2017-08-10 17:59:53

标签: javascript angularjs service-worker

我正在尝试在我的AngularJS项目中实现服务工作者,目的是如果服务器(在我的情况下是nginx)重新启动,那么必须在那段时间显示离线页面,但我坚持在另一种情况下。

我有一个页面,我使用GET请求列出项目,它从服务器获取响应(第一次),响应数据存储在缓存中但是我的页面在定期间隔内更新所以使用这种技术新数据没有立即显示。

这种方法有什么问题,请提出更好的方法。

文件夹结构

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

下面是我的服务工作者文件的代码

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 个答案:

答案 0 :(得分:1)

您在缓存中的key资源是request(因为您在cache.put(request, copy)函数中使用addToCache),但是您正在使用url检索它(例如/offline.html函数中的offlineResponse。您应与request中的cache匹配。