1、只有localhost 和 https 支持sw,注冊才有效。
2、ios部分手機不支持,安卓支持比較好。但是連了代理的環境下,較新的手機都會注冊sw失敗,報ssl證書有問題。目前連wifi代理的條件下,safar瀏覽器能注冊並緩存成功。
3、在html上寫這么一段代碼就能注冊sw,其中register第一個參數是指定注冊的sw文件,注意sw文件必須在當前頁面同級或者更上層。 第二個參數是指定作用的范圍,如果瀏覽器打開過這個html,並且注冊這個成功之后,那么scope范圍內的其它頁面也會受這個sw文件控制了。如果只想當前自己的頁面受sw控制,可以直接scope寫當前頁面的地址。
if ('serviceWorker' in navigator) { window.addEventListener('load', function () { //避免還沒load就去加載sw.js文件 浪費首屏顯示時間 navigator.serviceWorker.register('/test-sw.js', { scope: './' }).then(function (e) { console.log("Yes, it did.") }).catch(function (err) { console.log("No it didn't. This happened: ", err) }); }); }
4、sw控制頁面后,同域下的請求都會走sw的fetch劫持,如果出現http的圖片資源就會加載不出來,解決的辦法是在sw文件的fetch事件里做判斷,只有https的請求才去fetch並且緩存。代碼處理如下
5、貼一下整個sw文件的代碼
var CACHE_NAME = 'test-sw-7'; var addAll = ['jquery-1.4.2.min.js', 'index.css', 'spark-md5.js'] var util = { fetchPut: function (request, callback) { return fetch(request).then(function (response) { // 跨域的資源直接return if (!response || response.status !== 200 || response.type !== "basic") { return response; } util.putCache(request, response.clone()); typeof callback === 'function' && callback(); return response; }); }, putCache: function (request, resource) { var realUrl = request.url.split('?')[0]; console.log(111111, realUrl) var canCache = false; for (var i = 0; i < addAll.length; i++) { if(realUrl.indexOf(addAll[i]) >= 0) { canCache = true; } } if (request.method === "GET" && canCache ) { console.log('sw緩存', realUrl); caches.open(CACHE_NAME).then(function (cache) { cache.put(request, resource); }); } } }; self.addEventListener('fetch', function(event) { if(event.request.url.indexOf('https') != 0) return console.log('fetch', event.request.url) event.respondWith( caches.match(event.request).then(function(response) { // cache hit if (response) { return response; } return util.fetchPut(event.request.clone()); }) ); }); self.addEventListener('install', function(event) { console.log('install') event.waitUntil(self.skipWaiting()); }); self.addEventListener('activate', function(event) { console.log('activate') Promise.all([ //更新客戶端 caches.keys().then(cacheList => { return Promise.all( cacheList.map(cacheName => { console.log('已緩存的CACHE_NAME:', cacheName); if (cacheName !== CACHE_NAME) { console.log('刪除掉緩存CACHE_NAME:', cacheName); caches.delete(cacheName); } }) ) }) ]) });