2017-06-14 72 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鏈接上,它是否會工作? –