Progressive web app Uncaught (in promise) TypeErro

2019-03-26 16:17发布

问题:

I started learning PWA (Progressive Web App) and I have problem, console "throws" error Uncaught (in promise) TypeError: Failed to fetch.

Anyone know what could be the cause?

let CACHE = 'cache';

self.addEventListener('install', function(evt) {
    console.log('The service worker is being installed.');
    evt.waitUntil(precache());
});

self.addEventListener('fetch', function(evt) {
    console.log('The service worker is serving the asset.');
    evt.respondWith(fromCache(evt.request));
});
function precache() {
    return caches.open(CACHE).then(function (cache) {
        return cache.addAll([
            '/media/wysiwyg/homepage/desktop.jpg',
            '/media/wysiwyg/homepage/bottom2_desktop.jpg'
        ]);
    });
}
function fromCache(request) {
    return caches.open(CACHE).then(function (cache) {
        return cache.match(request).then(function (matching) {
            return matching || Promise.reject('no-match');
        });
    });
}

回答1:

I think this is due to the fact that you don't have a fallback strategy. event.respondWith comes with a promise which you have to catch if there's some error.

So, I'd suggest that you change your code from this:

self.addEventListener('fetch', function(evt) {        
    console.log('The service worker is serving the asset.');
    evt.respondWith(fromCache(evt.request));
});                   

To something like this:

addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        if (response) {
          return response;     // if valid response is found in cache return it
        } else {
          return fetch(event.request)     //fetch from internet
            .then(function(res) {
              return caches.open(CACHE_DYNAMIC_NAME)
                .then(function(cache) {
                  cache.put(event.request.url, res.clone());    //save the response for future
                  return res;   // return the fetched data
                })
            })
            .catch(function(err) {       // fallback mechanism
              return caches.open(CACHE_CONTAINING_ERROR_MESSAGES)
                .then(function(cache) {
                  return cache.match('/offline.html');
                });
            });
        }
      })
  );
});          

NOTE: There are many strategies for caching, what I've shown here is offline first approach. For more info this & this is a must read.



回答2:

I found a solution to the same error, in my case the error showed when the service worker could not find a file, fix it by following the network in dev tool of chrome session, and identified the nonexistent file that the service worker did not find and removed array of files to register.

  '/processos/themes/base/js/processos/step/Validation.min.js',
  '/processos/themes/base/js/processos/Acoes.min.js',
  '/processos/themes/base/js/processos/Processos.min.js',
  '/processos/themes/base/js/processos/jBPM.min.js',
  '/processos/themes/base/js/highcharts/highcharts-options-white.js',
  '/processos/themes/base/js/publico/ProcessoJsController.js',
 // '/processos/gzip_457955466/bundles/plugins.jawrjs',
 // '/processos/gzip_N1378055855/bundles/publico.jawrjs',
 // '/processos/gzip_457955466/bundles/plugins.jawrjs',
  '/mobile/js/about.js',
  '/mobile/js/access.js',


回答3:

I had the same error and in my case Adblock was blocking the fetch to an url which started by 'ad' (e.g. /adsomething.php)