-
-
Save danwoods/4dc19d744b753adce7a2 to your computer and use it in GitHub Desktop.
this.addEventListener("fetch", function(event) { | |
console.log('WORKER: fetch event in progress.'); | |
/* We should only cache GET requests, and deal with the rest of method in the | |
client-side, by handling failed POST,PUT,PATCH,etc. requests. | |
*/ | |
if (event.request.url !== 'https://myserver.ngrok.com/app.js') { | |
/* If we don't block the event as shown below, then the request will go to | |
the network as usual. | |
*/ | |
console.log('WORKER: fetch event ignored.', event.request.method, event.request.url); | |
return fetch(event.request); | |
} | |
/* Similar to event.waitUntil in that it blocks the fetch event on a promise. | |
Fulfillment result will be used as the response, and rejection will end in a | |
HTTP response indicating failure. | |
*/ | |
event.respondWith( | |
caches | |
/* This method returns a promise that resolves to a cache entry matching | |
the request. Once the promise is settled, we can then provide a response | |
to the fetch request. | |
*/ | |
.match(event.request) | |
.then(function(cached) { | |
/* Even if the response is in our cache, we go to the network as well. | |
This pattern is known for producing "eventually fresh" responses, | |
where we return cached responses immediately, and meanwhile pull | |
a network response and store that in the cache. | |
Read more: | |
https://ponyfoo.com/articles/progressive-networking-serviceworker | |
*/ | |
var networked = fetch(event.request) | |
// We handle the network request with success and failure scenarios. | |
.then(fetchedFromNetwork, unableToResolve) | |
// We should catch errors on the fetchedFromNetwork handler as well. | |
.catch(unableToResolve); | |
/* We return the cached response immediately if there is one, and fall | |
back to waiting on the network as usual. | |
*/ | |
console.log('WORKER: fetch event', cached ? '(cached)' : '(network)', event.request.url); | |
return cached || networked; | |
function fetchedFromNetwork(response) { | |
/* We copy the response before replying to the network request. | |
This is the response that will be stored on the ServiceWorker cache. | |
*/ | |
var cacheCopy = response.clone(); | |
console.log('WORKER: fetch response from network.', event.request.url); | |
caches | |
// We open a cache to store the response for this request. | |
.open(version + 'pages') | |
.then(function add(cache) { | |
/* We store the response for this request. It'll later become | |
available to caches.match(event.request) calls, when looking | |
for cached responses. | |
*/ | |
cache.put(event.request, cacheCopy); | |
}) | |
.then(function() { | |
console.log('WORKER: fetch response stored in cache.', event.request.url); | |
}); | |
// Return the response so that the promise is settled in fulfillment. | |
return response; | |
} | |
/* When this method is called, it means we were unable to produce a response | |
from either the cache or the network. This is our opportunity to produce | |
a meaningful response even when all else fails. It's the last chance, so | |
you probably want to display a "Service Unavailable" view or a generic | |
error response. | |
*/ | |
function unableToResolve () { | |
/* There's a couple of things we can do here. | |
- Test the Accept header and then return one of the `offlineFundamentals` | |
e.g: `return caches.match('/some/cached/image.png')` | |
- You should also consider the origin. It's easier to decide what | |
"unavailable" means for requests against your origins than for requests | |
against a third party, such as an ad provider. | |
- Generate a Response programmaticaly, as shown below, and return that. | |
*/ | |
console.log('WORKER: fetch request failed in both cache and network.'); | |
/* Here we're creating a response programmatically. The first parameter is the | |
response body, and the second one defines the options for the response. | |
*/ | |
return new Response('<h1>Service Unavailable</h1>', { | |
status: 503, | |
statusText: 'Service Unavailable', | |
headers: new Headers({ | |
'Content-Type': 'text/html' | |
}) | |
}); | |
} | |
}) | |
); | |
}); |
@jeffposnick The requested url I'm seeing the issue with (among others) is the /person/model
one I've shown in the images, but the issue happens with any URL that's authenticated with headers.
I've changed the fetch function to return undefined as opposed to a fetch of the resource, and am still seeing the extra call. I even see it when I remove the fetch handler. You're saying this implies that there's an extra service worker somewhere trying to handle the fetch that I'm unaware of? When I look at chrome://inspect/#service-workers I only see the one I'm expecting, when I look at chrome://serviceworker-internals I see the worker I'm expecting plus an additional redundant worker that's stopped...
@jeffposnick I'm hoping those images will spur an "ah-ha!" moment :)
It feels like I'm having the same issue as this user http://stackoverflow.com/a/33836695/3896422
What's the request URL (including URL parameters) that you're using when you see the unexpected behavior?
Your
fetch
handler will exit early withreturn fetch(event.request);
unless your request URL is "https://myserver.ngrok.com/app.js", but that seems odd. If you want to exit early and fall back to the default network behavior without any service worker involvement, you should just usereturn;
. The return value of thefetch
handler is ignored, and that extrafetch(event.request);
is effectively doing nothing, except maybe resulting in extra, confusing log statements in your Network panel.