离线时在 Progressive Web App 中处理获取请求

Handling fetch requests in Progressive Web App when offline

我一直在关注 Progressive Web Apps 上的 this tutorial,我正试图找到一种方法,在应用程序离线时向用户显示某种消息。到目前为止,我的代码与教程几乎相同:

var cacheName = 'demoPWA-v1';
var filesToCache = [
    '/',
    '/index.html',
    '/js/app.js',
    '/icons/pwa-256x256.png'
];

self.addEventListener('install', function(e) {
    console.log('[demoPWA - ServiceWorker] Install event fired.');
    e.waitUntil(
        caches.open(cacheName).then(function(cache) {
            console.log('[demoPWA - ServiceWorker] Caching app shell...');
            return cache.addAll(filesToCache);
        })
    );
});

self.addEventListener('activate', function(e) {
    console.log('[demoPWA - ServiceWorker] Activate event fired.');
    e.waitUntil(
        caches.keys().then(function(keyList) {
            return Promise.all(keyList.map(function(key) {
                if (key !== cacheName) {
                    console.log('[demoPWA - ServiceWorker] Removing old cache...', key);
                    return caches.delete(key);
                }
            }));
        })
    );
    return self.clients.claim();
});

self.addEventListener('fetch', function(e) {
    console.log('[demoPWA - ServiceWorker] Fetch event fired.', e.request.url);
    e.respondWith(
        caches.match(e.request).then(function(response) {
            if (response) {
                console.log('[demoPWA - ServiceWorker] Retrieving from cache...');
                return response;
            }
            console.log('[demoPWA - ServiceWorker] Retrieving from URL...');
            return fetch(e.request);
        })
    );
});

当我选中 Application > Service Workers 下 Chrome 中的 Offline 复选框时,我收到了一些错误,如下所示:

我想知道是否有某种方法可以处理此错误,并在这样做时向用户显示某种消息,告知他们他们处于离线状态。

以下是仅用于提醒的模组,然后您可以将提醒更改为使用 Jquery 或直接 DOM 更新您的 HTML 页面..

self.addEventListener('fetch', function(e) {
    console.log('[demoPWA - ServiceWorker] Fetch event fired.', e.request.url);
    e.respondWith(
        caches.match(e.request).then(function(response) {
            if (response) {
                console.log('[demoPWA - ServiceWorker] Retrieving from cache...');
                return response;
            }
            console.log('[demoPWA - ServiceWorker] Retrieving from URL...');
            return fetch(e.request).catch(function (e) {
               //you might want to do more error checking here too,
               //eg, check what e is returning..
               alert('You appear to be offline, please try again when back online');
            });
        })
    );
});

是的,你在做什么,这很有意义,只要你确定缓存不为空,因为你只打算用它来显示离线警告。

MDN的代码确实有问题,catch()没有用,我修改了一下,可以用了,至于catch(),我还没来得及解决问题,如果你找到解决办法首先,让我知道!这是代码:

var CACHE_VERSION = 1;

// Smallest identifier for a specific version of the cache
var CURRENT_CACHES = {
  font: 'OFFLINE_CACHE' + CACHE_VERSION
};

self.addEventListener('fetch', function(event) {
 // console.log(event);
// We only want to call event.respondWith() if this is a GET request for an HTML document.
  if (event.request.method === 'GET') {
    console.log('Handling fetch event for', event.request.url);

  event.respondWith(

    // Opens the cache object that starts with 'font'
    caches.open(CURRENT_CACHES['font']).then(function(cache) {
      return cache.match(event.request).then(function(response) {
        if (response) {
          console.log('Found cached answer:', response);
          return response;
        } else {
        //Did not find answer in cache
        return fetch(event.request).then(function(fetchresponse) {
        console.log("Request Result - redirected:" + fetchresponse.redirected + ", status:" + fetchresponse.status + ", statusText:" + fetchresponse.statusText + ", type:" + fetchresponse.type + ", url:" + fetchresponse.url);
        if(fetchresponse.status == '200' || fetchresponse.status == '201' || fetchresponse.status == '202' || fetchresponse.status == '203' || fetchresponse.status == '204' || fetchresponse.status == '206'){
               return fetchresponse;    
         } else {
         console.log('The request returned http code 30*, 40* or 50*.');
         return false;
         }    
        }).catch(function(e) {
         //Offline version
        return new Response('<html><title></title><strong>Sorry, You are offline!</strong></html>', {"status" : 202, "headers" : {"Content-Type" : "text/html; charset=utf-8"}});
        });
        }
      }).catch(function(error) {
        //This .catch () doesn't seem to work, as I said, but it won't give you any problems, it just takes up space.

        // Handles exceptions that come from match () or fetch ().

        console.error('  Error:', error);

        throw error;
      });
    })
  );
  };
});