Source code
Revision control
Copy as Markdown
Other Tools
const originalSwOption = new URL(location.href).searchParams.get('sw');
let swOption = originalSwOption;
if (swOption === 'fetch-handler-navigation-preload') {
self.addEventListener('activate', event => {
if (self.registration.navigationPreload) {
event.waitUntil(self.registration.navigationPreload.enable());
}
});
}
if (swOption === 'race-fetch-handler' ||
swOption === 'race-fetch-handler-to-fallback' ||
swOption === 'race-fetch-handler-modify-url') {
swOption = swOption.substring('race-'.length);
self.addEventListener('install', event => {
event.addRoutes([{
condition: { urlPattern: { pathname: '/**/counting-executor.py' } },
source: 'race-network-and-fetch-handler'
}]);
});
}
const interceptedRequests = [];
self.addEventListener('message', event => {
if (event.data === 'getInterceptedRequests') {
event.source.postMessage(interceptedRequests);
}
});
if (swOption !== 'no-fetch-handler') {
self.addEventListener('fetch', event => {
// Intercept the prefetched and navigated URLs only (e.g. do not intercept
// subresource requests related to `/common/dispatcher/dispatcher.js`).
if (!event.request.url.includes('counting-executor.py')) {
return;
}
const headers = {};
event.request.headers.forEach((value, key) => {
headers[key] = value;
});
const interceptedRequest = {
request: {
url: event.request.url,
headers: headers,
},
clientId: event.clientId,
resultingClientId: event.resultingClientId
};
interceptedRequests.push(interceptedRequest);
if (swOption === 'fetch-handler') {
event.respondWith(fetch(event.request));
} else if (swOption === 'fetch-handler-synthetic') {
const finalUrl = new URL(event.request.url).searchParams.get('location');
if (finalUrl) {
event.respondWith(Response.redirect(finalUrl));
} else {
// Fallback to the network.
}
} else if (swOption === 'fetch-handler-modify-url') {
// The "Sec-Purpose: prefetch" header is dropped in fetch-handler-modify-*
const url = new URL(event.request.url);
url.searchParams.set('intercepted', 'true');
if (originalSwOption === 'race-fetch-handler-modify-url') {
// See the comment in `basic.sub.https.html` for delay value.
url.searchParams.set('delay', '500');
}
event.respondWith(fetch(url, {headers: event.request.headers}));
} else if (swOption === 'fetch-handler-modify-referrer') {
event.respondWith(fetch(event.request,
{referrer: new URL('/intercepted', location.href).href}));
} else if (swOption === 'fetch-handler-navigation-preload') {
event.respondWith((async () => {
try {
if (event.preloadResponse === 'undefined') {
interceptedRequest.preloadResponse = 'undefined';
return fetch(event.request);
}
const response = await event.preloadResponse;
if (response) {
interceptedRequest.preloadResponse = 'resolved';
return response;
} else {
interceptedRequest.preloadResponse = 'resolved to undefined';
return fetch(event.request);
}
} catch(e) {
interceptedRequest.preloadResponse = 'rejected';
throw e;
}
})());
} else {
// Do nothing to fallback to the network.
}
});
}