forked from visiky/kasmine.blog
-
Notifications
You must be signed in to change notification settings - Fork 1
/
sw.js
executable file
·117 lines (101 loc) · 4.18 KB
/
sw.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/* ===========================================================
* sw.js
* ========================================================== */
const version = "1.0.0",
CACHE = "precache." + version,
RUNTIME = "runtime",
ROOT = "/kasmine.blog",
ASSETS = `${ROOT}/assets`
HOSTNAME_WHITELIST = [self.location.hostname],
offlineURL = `${ROOT}/offline.html`,
installFilesEssential = [
// `${ASSETS}/css/bootstrap.css`, `${ASSETS}/css/kasmine-blog.css`,
// `${ASSETS}/css/style.css`,
`${ASSETS}/img/Calendar.svg`,
`${ASSETS}/img/home-bg.jpg`,
`${ASSETS}/img/avatar-kasmine.jpg`,
`${ROOT}/pwa/manifest.json`
].concat(offlineURL),
installFilesDesirable = [`${ASSETS}/img/404-bg.jpg`];
function installStaticFiles() {
return caches.open(CACHE) // create a new cache
.then(cache => {
/**
* @param {array} request URLs;return {Promise}
**/
cache.addAll(installFilesDesirable);
return cache.addAll(installFilesEssential);
})
}
/**
* @Lifecycle Install
* waitUntil() : installing ====> installed
* skipWaiting() : waiting(installed) ====> activating
*/
self.addEventListener('install', e => {
/* cache core files */
e.waitUntil(installStaticFiles().then(cache => self.skipWaiting()));
});
function clearOldCaches() {
return caches
.keys()
.then(keylist => {
return Promise.all(keylist.filter(key => key != CACHE)
/**
* @param cache entry
* retrun {Promise}
**/
.map(key => caches.delete(key)));
});
}
self.addEventListener("activate", event => {
console.log("service worker :activated");
event.waitUntil(
// clearOldCaches() 设置本身为 active 的service worker ?TODO:作用? .then(() =>
// self.clients.claim())
self.clients.claim());
});
// A navigate request is created only while navigating between documents. The
// Util Function to detect and polyfill req.mode="navigate" request.mode of
// 'navigate' is unfortunately not supported in Chrome versions older than 49.0,
// so we need to include a less precise fallback, which checks for a GET request
// with an Accept: text/html header.
const isNavigationReq = (req) => (req.mode === 'navigate' || (req.method === 'GET' && req.headers.get('accept').includes('text/html')));
const getFixedUrl = (req) => {
var now = Date.now(),
url = new URL(req.url);
url.protocol = self.location.protocol;
url.search += (url.search
? '&'
: '?') + 'cache-bust=' + now;
return url.href;
}
self.addEventListener('fetch', event => {
// e.g.,[cors, no-cors, cors-with-forced-preflight, same-origin, or navigate.]
// console.log(`MODE: ${event.request.mode}`); // no-cors Skip non-GET requests
// and some of cross-origin requests, like those for Google Analytics.
if (event.request.method !== "GET" || HOSTNAME_WHITELIST.indexOf(new URL(event.request.url).hostname) == -1)
return;
// logs for debugging console.log(`fetch ${event.request.url}`);
const cached = caches.match(event.request);
const fixedUrl = getFixedUrl(event.request);
const fetched = fetch(fixedUrl, {cache: "no-store"});
const fetchedCopy = fetched.then((response) => response.clone());
// event.respondWith( caches.match(event.request).then(function(response) {
// return response || fetch(event.request).then(function(response) { //
// console.log('Response from network is:', response); return response;
// }).catch(function(error) { // console.error('Fetching failed:',
// error); caches.match(offlineURL); }); }) ); check if there is
// something in cache if not,about to fetch from network if neither yields a
// response,return offline-pages USE PROMISE!
event.respondWith(Promise.race([fetched.catch(() => cached), cached]).then(response => response || fetched).catch(() => caches.match(offlineURL)));
// Update the cache with the version we fetched (only for ok status)
event.waitUntil(Promise.all([
fetchedCopy, caches.open(RUNTIME)
])
/**
* The put() method of the Cache interface allows key/value pairs to be added to the current Cache object. @param {URL,RESPONSE}
*/
.then(([response, cache]) => response.ok && cache.put(event.request, response)).catch(() => {/* eat any errors */
}));
});