2
  • 我正在嘗試使用脫機第一策略構建PWA
    • 源文件的服務器是NodeJS服務器
    • 我目前正在測試這個在本地主機節點服務器(不確定它有影響嗎?)。
    • 服務人員+緩存看起來不錯,但處於離線模式我只收到Chrome離線頁面

讓我們來看看細節:服務工作人員不在離線模式下使用節點js服務器

其供應(通過http://localhost:8080/place/test網址)頁面有一些客戶端的JS,我在其中註冊服務工作者:

client.js

if ('serviceWorker' in navigator) { 
     navigator.serviceWorker 
       .register(rootPath+'/js/service-worker.js') 
       .then(function() { console.log('Service Worker Registered'); }); 
    } 

服務worker.js(基於谷歌PWA教程)

var cacheName = 'myCacheVersion'; 
var filesToCache = [ 
    '../', 
    '../place/test', 
    '../js/client.js', 
    '../js/service-worker.js', 
    "../css/style.css" 
]; 


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

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

self.addEventListener('fetch', function(e) { 
    console.log('[ServiceWorker] Fetch', e.request.url); 
    e.respondWith(
    caches.match(e.request).then(function(response) { 
     return response || fetch(e.request); 
    }) 
); 
}); 

在開發工具控制檯,一切似乎很動聽:

  • 的SW註冊
  • 緩存包含我想緩存的元素

但是當我檢查離線模式複選框並刷新我的網頁網址:http://localhost:8080/place/test,我只獲得Google Chrome離線網頁

=>我在那裏錯過了什麼?(它有對的NodeJS做?與本地主機的環境?我的執行?)

我一直是這樣一個,而現在有點掙扎......

我已經檢查了「應用程序「選項卡和我的服務工作人員顯示爲激活並正在運行。

注:如果發現了類似的問題在這裏,但沒有令人滿意的答案在那裏:Service worker not run in offline mode using nodejs server

+0

你說SW已註冊; (如同你對鏈接到的其他問題的評論一樣)是否顯示在「應用程序」選項卡中? –

+1

是的,它顯示爲「激活並正在運行」 –

回答

3

從根本上說,這是同樣的問題在這裏得到解答:Service worker is caching files but fetch event is never fired

如果您在控制檯看,你將會看到,在安裝,激活,緩存和註冊都發生時,「獲取」不會。這是因爲您找到了js之下的服務工作人員,因此出於安全原因,Chrome(etc)不會將其用於任何除相同目錄或以下目錄之外的任何URL。

如果您將client.jsservice-worker.js放在同一級別而不是在js子目錄中,它將全部開始工作。這將需要更新文件的內容,我將在下面顯示以供參考。

一個小小的警告:我愚蠢地使用Windows上的IIS來處理這個問題,並且在Chrome和Chrome之間,他們像過時的JS文件位置一樣死死抱住了緩存的HTML文件。我不得不將它們複製到一個子目錄中,創建新的URL以測試解決方案。

index.html

<head> 
<script src="client.js"></script> 
</head> 
<body> 
<a href="cachetest.html">link to ct</a> 
</body> 

cachetest.html

<head> 
<script src="client.js"></script> 
</head> 
<body>cachetest</body> 

client.js

if ('serviceWorker' in navigator) { 
    navigator.serviceWorker 
      .register('service-worker.js') 
      .then(function() { console.log('Service Worker Registered'); }); 
} 

serviceworker.js

var cacheName = 'myCacheVersion'; 
var filesToCache = [ 
    '', 
    'cachetest.html', 
    'client.js', 
    'service-worker.js', 
// "css/style.css" 
]; 


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

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

self.addEventListener('fetch', function(e) { 
    console.log('[ServiceWorker] Fetch', e.request.url); 
    e.respondWith(
    caches.match(e.request).then(function(response) { 
     return response || fetch(e.request); 
    }) 
); 
}); 
+1

你釘了它!我只需**將我的service-worker.js移動到我的根目錄**,並對文件路徑進行一些更改+緩存文件列表路徑以使其工作... 稍後注意:請記住服務人員只能訪問其級別或以下...非常感謝! (我提出了你的答案,但在這裏是新的,它現在還沒有顯示......) –

+0

謝謝!祝你好運與其他的東西。我會看看這是否也是對其他問題的答案。 –

+0

或者,你可以! :-) –