2017-06-14 46 views
3

我在我的支持脱机浏览的渐进式Web应用程序中使用了Cache-first策略。我已经注意到,离线浏览工作正常,但当我更新网站上的内容时,它仍然显示旧的东西。我不知道我的代码有什么问题,因为我想在加载离线前检查是否有更新内容。我有manifest.json的服务的worker.jsOfflinepage.jsmain.jsCache-First策略中内容更改时网站未更新

这里是我的服务worker.js代码,我已经使用:

 //service worker configuration 
     'use strict'; 

     const 
     version = '1.0.0', 
     CACHE = version + '::PWA', 
     offlineURL = '/offline/', 
     installFilesEssential = [ 
     '/', 
      '/manifest.json', 
      '/theme/pizza/css/style.css', 
      '/theme/pizza/css/font-awesome/font-awesome.css', 
      '/theme/pizza/javascript/script.js', 
      '/theme/pizza/javascript/offlinepage.js', 
      '/theme/pizza/logo.png', 
      '/theme/pizza/icon.png' 
     ].concat(offlineURL), 
     installFilesDesirable = [ 
      '/favicon.ico', 
     '/theme/pizza/logo.png', 
      '/theme/pizza/icon.png' 
     ]; 

     // install static assets 
     function installStaticFiles() { 

     return caches.open(CACHE) 
      .then(cache => { 

      // cache desirable files 
      cache.addAll(installFilesDesirable); 

      // cache essential files 
      return cache.addAll(installFilesEssential); 

      }); 

     } 
     // clear old caches 
     function clearOldCaches() { 

     return caches.keys() 
      .then(keylist => { 

      return Promise.all(
       keylist 
       .filter(key => key !== CACHE) 
       .map(key => caches.delete(key)) 
      ); 

      }); 

     } 

     // application installation 
     self.addEventListener('install', event => { 

     console.log('service worker: install'); 

     // cache core files 
     event.waitUntil(
      installStaticFiles() 
      .then(() => self.skipWaiting()) 
     ); 

     }); 

     // application activated 
     self.addEventListener('activate', event => { 

     console.log('service worker: activate'); 

     // delete old caches 
     event.waitUntil(
      clearOldCaches() 
      .then(() => self.clients.claim()) 
     ); 

     }); 

     // is image URL? 
     let iExt = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp'].map(f => '.' + f); 
     function isImage(url) { 

     return iExt.reduce((ret, ext) => ret || url.endsWith(ext), false); 

     } 


     // return offline asset 
     function offlineAsset(url) { 

     if (isImage(url)) { 

      // return image 
      return new Response(
      '<svg role="img" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title>offline</title><path d="M0 0h400v300H0z" fill="#eee" /><text x="200" y="150" text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="50" fill="#ccc">offline</text></svg>', 
      { headers: { 
       'Content-Type': 'image/svg+xml', 
       'Cache-Control': 'no-store' 
      }} 
     ); 

     } 
     else { 

      // return page 
      return caches.match(offlineURL); 

     } 

     } 

     // application fetch network data 
     self.addEventListener('fetch', event => { 

     // abandon non-GET requests 
     if (event.request.method !== 'GET') return; 

     let url = event.request.url; 

     event.respondWith(

      caches.open(CACHE) 
      .then(cache => { 

       return cache.match(event.request) 
       .then(response => { 

        if (response) { 
        // return cached file 
        console.log('cache fetch: ' + url); 
        return response; 
        } 

        // make network request 
        return fetch(event.request) 
        .then(newreq => { 

         console.log('network fetch: ' + url); 
         if (newreq.ok) cache.put(event.request, newreq.clone()); 
         return newreq; 

        }) 
        // app is offline 
        .catch(() => offlineAsset(url)); 

       }); 

      }) 

     ); 

     }); 
+0

看起来你服务从缓存中的网页,即使用户处于联机状态。我只会将解决方案应用于离线用户。因此,当他们再次上线时,我们可以清除缓存并提供有效的页面。 –

+0

@DmitriyNesteryuk你是对的。我真的想要一种方法来确保所有用户获得最新的数据并确保页面加载更快 –

回答

1

我解决了问题,如下图所示:如果用户即离线缓存从其他负载获取来自网络

// application fetch network data 
self.addEventListener('fetch', event => { 

    // abandon non-GET requests 
    if (event.request.method !== 'GET') return; 

    let url = event.request.url; 

    event.respondWith(

    caches.open(CACHE) 
     .then(cache => { 

     return cache.match(event.request) 
      .then(response => { 

      if (response && !navigator.onLine) { 
       // return cached file 
       console.log('cache fetch: ' + url); 
       return response; 
       } 
       // make network request 
       return fetch(event.request) 
       .then(newreq => { 

        console.log('network fetch: ' + url); 
        if (newreq.ok) cache.put(event.request, newreq.clone()); 
        return newreq; 

       }) 
       // app is offline 
       .catch(() => offlineAsset(url)); 



      }); 

     }) 

); 

}); 
1

添加[VERSION]你的链接的src?

例如:

<script type="text/javascript" src="your_file.js?1500"></script> 

,每次您更新的代码只需将号码添加到您的版本。

其实这是重复问题look here for other的解决方案。

+0

这一个没有效果。只有当我删除旧缓存并重新加载页面时,更新后的内容才会更新。没有先清除缓存的情况下重新加载可确保显示旧内容。也许这是服务人员的弱点。虽然我可能是错的。 –

+0

你测试它在其他浏览器? –

+0

是的,我有。并且如果我将它附加到CSS链接上,它是否会工作? –