Dear js gurus in my timeline, is this the correct way to exclude urls from the power of ServiceWorkers?
(...) self.addEventListener('fetch', function (event) { var request = event.request; // if is request for cms admin, do nothing. if(request.url.indexOf('/blog/wp-admin/') !== -1){ return; } // Always fetch non-GET requests from the network if (request.method !== 'GET') { event.respondWith( fetch(request) .catch(function () { return caches.match('/offline.html'); }) ); return; } (...) |
Sorry for asking, but I'm still in baby step mode for this new and exiting power-up the web has now, and I'm trying to counter-act some strange effects I'm getting when I use my site's backend: Everytime a Ajax-y thing happens, like uploading a picture or deleting posts from an overview/list, the page will display the code of the Serviceworker-JS. The desired action worked, though, and by using the "back" button of the browser, the backend is workable again.
I haven't had this effect since I included the lines above, but frankly I have no idea what side effects this may cause elsewhere.
(living example: webrocker.de/sw.js)
11 Reaktionen zu “Wrestling with the ServiceWorker”
@webrocker LGTM.
@webrocker LGTM
@mxstbr @fhemberger danke. old fart musste erstmal abkürzungen kucken gehen ;-)
@mxstbr @fhemberger btw wie würde man sicherstellen, dass das "/blog/wp-admin/" am Anfang der url steht? fürchte, das wird komplex, weil >
@mxstbr @fhemberger > man dann ja erstmal das "https://(www.)" strippen müsste…?
@webrocker @fhemberger (regex101.com/#javascript ist super um solche Sachen zu probieren)
@mxstbr riecht es hier nach rtfm? ;-) @fhemberger
@webrocker @fhemberger kannst du nicht nach webrocker.de/blog/wp-admin filtern? Und/oder "^/blog/wp-admin"?
@webrocker @fhemberger neinnein, ich find das Tool nur echt super und hab grad selber keinen Plan :-)
Ich hab das bei mir so (oder so ähnlich) umgesetzt:
Prinzip: wenn die fetch-Anfrage mit einem der requests aus dem neverCache-Array matcht (mit Deiner https-BaseURL), dann bitte nix cachen, aber im Notfall die offline-Seite anzeigen).
Prinzip ist das gleiche, aber ich wollte mehrere Dateien explizit nicht cachen... kannste auch unter /serviceworker.js anschauen :)
Motivated by the sudden appearance of the "Add to home screen" prompt, I spent the last couple of hours to tune my Service Worker / caching behaviour:
- I can now exclude parts of my site from the service worker. This was an important feature for me, since the WordPress backend didn't sit too well with stubborn cached items.
- I established a number of caches for different items:
-- a "static" cache that has the base css and the page that gets displayed when the network is offline.
-- a "content" cache, that stores up to 25 URLs a visitor has, well, visited, while being online.
-- an "image" cache, that stores up to 45 image files, and finally
-- an "asset" cache for up to 35 files (everything that is not HTML and not an image).
The limits are rather random, but I think each cache has an build-in maximum of 50 entries (?), so to see if it works, I choosed numbers smaller than that.
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
'use strict';
(function() {
// Update 'version' if you need to refresh the cache
const version = '0.1.1';
const staticCache = 'wbr_static';
const contentCache = 'wbr_content';
const imgCache = 'wbr_images';
const assetCache = 'wbr_assets';
const staticCacheName = version + '_' + staticCache;
const contentCacheName = version + '_' + contentCache;
const imgCacheName = version + '_' + imgCache;
const assetCacheName = version + '_' + assetCache;
// urls that should not be controlled/cached
const neverCache = [
'piwik',
'/jaguar/',
'/blog/wp-admin/'
];
// helper for checking the neverCache array
var testPos = function(cur,idx,arr){
// 'this' will be triggered by the 'thisVar' param in array.some(callback,thisVar),
// i.e. neverCache.some(testPos,request.url)
if( this.indexOf(cur) !== -1 ){
return true;
}
return false;
}
// Store core files in a cache (including a page to display when offline)
var updateStaticCache = function() {
return caches.open( staticCacheName )
.then(function (cache) {
return cache.addAll([
'/blog/wp-content/themes/wbr-theme/style.css',
'/blog/wp-content/uploads/2016/04/image-6-530x398.png',
'/',
'/offline.html'
]);
});
};
// Put an item in a specified cache
var stashInCache = function(cacheName, request, response) {
caches.open(cacheName)
.then(function (cache) {
cache.put(request, response);
});
};
// Limit the number of items in a specified cache.
var trimCache = function(cacheName, maxItems) {
caches.open(cacheName)
.then(function (cache) {
cache.keys()
.then(function (keys) {
if (keys.length > maxItems) {
cache.delete(keys[0])
.then(trimCache(cacheName, maxItems));
}
});
});
};
// Remove caches whose name is no longer valid
var clearOldCaches = function() {
return caches.keys()
.then(function (keys) {
return Promise.all(keys
.filter(function (key) {
return key.indexOf(version) !== 0;
})
.map(function (key) {
return caches.delete(key);
})
);
})
}
self.addEventListener('install', function (event) {
event.waitUntil(updateStaticCache()
.then(function () {
return self.skipWaiting();
})
);
});
self.addEventListener('activate', function (event) {
event.waitUntil(clearOldCaches()
.then(function () {
return self.clients.claim();
})
);
});
self.addEventListener('message', function(event) {
if (event.data.command == 'trimCaches') {
trimCache(contentCacheName, 25);
trimCache(imgCacheName, 45);
trimCache(assetCacheName, 35);
}
});
self.addEventListener('activate', function (event) {
event.waitUntil(
caches.keys()
.then(function (keys) {
// Remove caches whose name is no longer valid
return Promise.all(keys
.filter(function (key) {
//console.log(key);
//console.log(key.indexOf(version) !== 0);
return key.indexOf(version) !== 0;
})
.map(function (key) {
return caches.delete(key);
})
);
})
);
});
self.addEventListener('fetch', function (event) {
var request = event.request;
// if is request for cms admin, do nothing.
if( neverCache.some(testPos,request.url)){
return
}
// Always fetch non-GET requests from the network
if (request.method !== 'GET') {
event.respondWith(
fetch(request)
.catch(function () {
return caches.match('/offline.html');
})
);
return;
}
// For HTML requests, try the network first, fall back to the cache, finally the offline page
if (request.headers.get('Accept').indexOf('text/html') !== -1) {
// Fix for Chrome bug: https://code.google.com/p/chromium/issues/detail?id=573937
if (request.mode != 'navigate') {
request = new Request(request.url, {
method: 'GET',
headers: request.headers,
mode: request.mode,
credentials: request.credentials,
redirect: request.redirect
});
}
event.respondWith(
fetch(request)
.then(function (response) {
// Stash a copy of this page in the cache
var copy = response.clone();
stashInCache(contentCacheName, request, copy);
return response;
})
.catch(function () {
return caches.match(request)
.then(function (response) {
return response || caches.match('/offline.html');
})
})
);
return;
}
// For non-HTML requests,
// - look in the cache first,
// - fall back to the network, cache it,
// - else show offline img if is image request
event.respondWith(
caches.match(request)
.then(function (response) {
return response || fetch(request)
// update asset | image cache
.then(function (response) {
// Stash a copy of this page in the cache.
var copy = response.clone();
var myCache = assetCacheName;
if (request.headers.get('Accept').indexOf('image') !== -1) {
myCache = imgCacheName;
}
stashInCache(myCache, request, copy);
return response;
})
.catch(function () {
// If the request is for an image, show an offline placeholder
if (request.headers.get('Accept').indexOf('image') !== -1) {
return new Response('Offlineoffline', { headers: { 'Content-Type': 'image/svg+xml' }});
}
});
})
);
});
})();
I'm quite pleased with myself because the script still works after all these changes, and I think I'm beginning to grasp how this hot new stuff is supposed to work :-)
Thanks Jeremy @adactio for the "blogServiceworker" gist, and Steffen @webgefrickel for the idea for the "neverCache" array.
Kommentare sind geschlossen.