如何从PWA中的缓存中排除特定页面?

时间:2019-12-18 08:21:56

标签: service-worker progressive-web-apps

我正在一个运行良好的网站上使用Progressive Web App,现在我希望某些页面不应该被缓存。 我不应该缓存的网址保存在JavaScript变量中

var cacheExclude = [
    '/user/register',
    '/item/new',
    '/login'
];

我希望离线访问这些页面时,应改为显示“ /offline.html ”。

下面是我的服务工作者,负责处理缓存

self.addEventListener("fetch", function(event) {

    //Fetch from network and cache
    var fetchFromNetwork = function(response) {
        var cacheCopy = response.clone();
        if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
            caches.open(version + 'pages').then(function(cache) {
                cache.put(event.request, cacheCopy).then(function() {
                    limitCache(cache, 25);
                })
            });
        } else if (event.request.headers.get('Accept').indexOf('image') != -1) {
            caches.open(version + 'images').then(function(cache) {
                cache.put(event.request, cacheCopy).then(function() {
                    limitCache(cache, 10); 
                });
            });
        } else {
            caches.open(version + 'assets').then(function add(cache) {
                cache.put(event.request, cacheCopy);
            });
        }

        return response;
    }

    //Fetch from network failed
    var fallback = function() {
        if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
            return caches.match(event.request).then(function (response) {
                return response || caches.match('/offline.html');
            })
        } 
    }

    //This service worker won't touch the admin area
    if (event.request.url.match(/admin/)) {
        return;
    }

    //This service worker won't touch non-get requests
    if (event.request.method != 'GET') {
        return;
    }

    //For HTML requests, look for file in network, then cache if network fails.
    if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
                    event.respondWith(fetch(event.request).then(fetchFromNetwork, fallback));
        return;
            }

    //For non-HTML requests, look for file in cache, then network if no cache exists.
    event.respondWith(
        caches.match(event.request).then(function(cached) {
            return cached || fetch(event.request).then(fetchFromNetwork, fallback);
        })
    )
});

如果任何cacheExclude路径匹配,我只是想重定向到脱机页面?

1 个答案:

答案 0 :(得分:1)

如果要排除某些路径,可以使用Glob求反:

var cacheExclude = [
    '!(*/user/register'),
    '!(*/item/new'),
    '!(*/login')
];

如果匹配的glob表达式之前没有任何内容,最终您可以跳过*。

但是,如果任何 cacheExclude 路径具有匹配项,您也可以简单地重定向到脱机页面,因此不需要取反Glob表达式。

var cacheExclude = [
    '/user/register',
    '/item/new',
    '/login'
];

hasUrlCacheExcludeMatch(url) {
  // Note: .endsWith() does not work in IE. 
  return cacheExclude.some(path => url.endsWith(path));
}


self.addEventListener('fetch', function(event) {
  if (event.request.method === 'GET' &&
      event.request.headers.get('accept').indexOf('text/html') !== -1) {

      if(hasUrlCacheExcludeMatch(event.request.url)){
        const cachedResponse = await cache.match('/offline.html');
        return cachedResponse;
      }

      // Your other code...
  }
});