作用:
可以使你的應(yīng)用先訪問本地緩存資源兄朋,所以在離線狀態(tài)時(shí)兴泥,在沒有通過網(wǎng)絡(luò)接收到更多的數(shù)據(jù)前楔敌,仍可以提供基本的功能博脑。
使用前的設(shè)置:
Chrome中需要開啟相關(guān)配置: 訪問 chrome://flags 并開啟 experimental-web-platform-features; 重啟瀏覽器 (注意:有些特性在Chrome中沒有默認(rèn)開放支持);另外屁倔,你需要通過 HTTPS 來訪問你的頁面 — 出于安全原因脑又,Service Workers 要求要在必須在 HTTPS 下才能運(yùn)行,localhost 也被瀏覽器認(rèn)為是安全源锐借。
簡單的例子
這是把express和sw-test簡單結(jié)合的一個(gè)小demo, 項(xiàng)目運(yùn)行起來訪問
http://localhost:3000/sw-test/index.html , 然后終止此服務(wù)依然能訪問相應(yīng)資源问麸。Github
相關(guān)代碼
- /public/sw-test/app.js
- 首先判斷了瀏覽器是否支持
- 調(diào)用 register 方法注冊 service worker, 第一個(gè)參數(shù)是運(yùn)行 service worker 的
js 文件, 第二個(gè) scope 參數(shù)是選填的,可以被用來指定你想讓 service worker 控制的內(nèi)容的子目錄钞翔。 在這個(gè)例子严卖,我們指定了 '/sw-test/',即 http://localhost:3000/sw-test/ 下的請(qǐng)求會(huì)被捕獲, 被指定的資源會(huì)被緩存布轿。 - register 方法返回一個(gè) Promise , 進(jìn)行正確錯(cuò)誤處理哮笆。
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw-test/sw.js', { scope: '/sw-test/' }).then(function(reg) {
// registration worked
console.log('Registration succeeded. Scope is ' + reg.scope);
}).catch(function(error) {
// registration failed
console.log('Registration failed with ' + error);
});
}
-
/public/sw-test/sw.js
核心文件,監(jiān)聽安裝事件, 打開緩存 v1 增加需要緩存資源 request url list, 截取被控文件下請(qǐng)求, 如果不存在該緩存則進(jìn)行緩存處理
- 監(jiān)聽了 install 事件, event.waitUntil 主要用在 Install, activate 事件中, 在服務(wù)工作線程中来颤,延長事件的壽命從而阻止瀏覽器在事件中的異步操作完成之前終止服務(wù)工作線程。
-
Cache 接口提供緩存的 Request,
Response 對(duì)象對(duì)的存儲(chǔ)機(jī)制稠肘,例如作為ServiceWorker
生命周期的一部分福铅。 Cache 接口像 workers 一樣, 是暴露在 window 作用域下的。盡管它被定義在 service worker 的標(biāo)準(zhǔn)中, 但是它不必一定要配合 service worker 使用.Cache詳細(xì)API - event.respondWith 方法旨在包裹代碼项阴,這些代碼為來自受控頁面的request生成自定義的response滑黔,查看更多。response.clone() 創(chuàng)建了一個(gè)響應(yīng)對(duì)象的克隆环揽,這個(gè)對(duì)象在所有方面都是相同的略荡,但是存儲(chǔ)在一個(gè)不同的變量中。防止多次使用篡改了對(duì)象歉胶。
self.addEventListener('install', function(event) {
event.waitUntil(
caches.open('v1').then(function(cache) {
return cache.addAll([
'/sw-test/',
'/sw-test/index.html',
'/sw-test/style.css',
'/sw-test/app.js',
'/sw-test/image-list.js',
'/sw-test/star-wars-logo.jpg',
'/sw-test/gallery/bountyHunters.jpg',
'/sw-test/gallery/myLittleVader.jpg',
'/sw-test/gallery/snowTroopers.jpg'
]);
})
);
});
self.addEventListener('fetch', function(event) {
event.respondWith(caches.match(event.request).then(function(response) {
// caches.match() always resolves
// but in case of success response will have value
if (response !== undefined) {
return response;
} else {
return fetch(event.request).then(function (response) {
// response may be used only once
// we need to save clone to put one copy in cache
// and serve second one
let responseClone = response.clone();
caches.open('v1').then(function (cache) {
cache.put(event.request, responseClone);
});
return response;
}).catch(function () {
return caches.match('/sw-test/gallery/myLittleVader.jpg');
});
}
}));
});
版本更新刪除舊緩存
- 監(jiān)聽 activate 事件, 如當(dāng)前版本 v2汛兜,刪除與當(dāng)前不匹配緩存數(shù)據(jù)。
this.addEventListener('activate', function(event) {
var cacheWhitelist = ['v2'];
event.waitUntil(
caches.keys().then(function(keyList) {
return Promise.all(keyList.map(function(key) {
if (cacheWhitelist.indexOf(key) === -1) {
return caches.delete(key);
}
}));
})
);
});