basic-service-worker.js (3610B)
1 const originalSwOption = new URL(location.href).searchParams.get('sw'); 2 let swOption = originalSwOption; 3 4 if (swOption === 'fetch-handler-navigation-preload') { 5 self.addEventListener('activate', event => { 6 if (self.registration.navigationPreload) { 7 event.waitUntil(self.registration.navigationPreload.enable()); 8 } 9 }); 10 } 11 12 if (swOption === 'race-fetch-handler' || 13 swOption === 'race-fetch-handler-to-fallback' || 14 swOption === 'race-fetch-handler-modify-url') { 15 swOption = swOption.substring('race-'.length); 16 self.addEventListener('install', event => { 17 event.addRoutes([{ 18 condition: { urlPattern: { pathname: '/**/counting-executor.py' } }, 19 source: 'race-network-and-fetch-handler' 20 }]); 21 }); 22 } 23 24 const interceptedRequests = []; 25 26 self.addEventListener('message', event => { 27 if (event.data === 'getInterceptedRequests') { 28 event.source.postMessage(interceptedRequests); 29 } 30 }); 31 32 if (swOption !== 'no-fetch-handler') { 33 self.addEventListener('fetch', event => { 34 35 // Intercept the prefetched and navigated URLs only (e.g. do not intercept 36 // subresource requests related to `/common/dispatcher/dispatcher.js`). 37 if (!event.request.url.includes('counting-executor.py')) { 38 return; 39 } 40 41 const headers = {}; 42 event.request.headers.forEach((value, key) => { 43 headers[key] = value; 44 }); 45 const interceptedRequest = { 46 request: { 47 url: event.request.url, 48 headers: headers, 49 }, 50 clientId: event.clientId, 51 resultingClientId: event.resultingClientId 52 }; 53 interceptedRequests.push(interceptedRequest); 54 55 if (swOption === 'fetch-handler') { 56 event.respondWith(fetch(event.request)); 57 } else if (swOption === 'fetch-handler-synthetic') { 58 const finalUrl = new URL(event.request.url).searchParams.get('location'); 59 if (finalUrl) { 60 event.respondWith(Response.redirect(finalUrl)); 61 } else { 62 // Fallback to the network. 63 } 64 } else if (swOption === 'fetch-handler-modify-url') { 65 // The "Sec-Purpose: prefetch" header is dropped in fetch-handler-modify-* 66 // cases in Step 33 of // https://fetch.spec.whatwg.org/#dom-request 67 // because it's a https://fetch.spec.whatwg.org/#forbidden-request-header 68 const url = new URL(event.request.url); 69 url.searchParams.set('intercepted', 'true'); 70 if (originalSwOption === 'race-fetch-handler-modify-url') { 71 // See the comment in `basic.sub.https.html` for delay value. 72 url.searchParams.set('delay', '500'); 73 } 74 event.respondWith(fetch(url, {headers: event.request.headers})); 75 } else if (swOption === 'fetch-handler-modify-referrer') { 76 event.respondWith(fetch(event.request, 77 {referrer: new URL('/intercepted', location.href).href})); 78 } else if (swOption === 'fetch-handler-navigation-preload') { 79 event.respondWith((async () => { 80 try { 81 if (event.preloadResponse === 'undefined') { 82 interceptedRequest.preloadResponse = 'undefined'; 83 return fetch(event.request); 84 } 85 const response = await event.preloadResponse; 86 if (response) { 87 interceptedRequest.preloadResponse = 'resolved'; 88 return response; 89 } else { 90 interceptedRequest.preloadResponse = 'resolved to undefined'; 91 return fetch(event.request); 92 } 93 } catch(e) { 94 interceptedRequest.preloadResponse = 'rejected'; 95 throw e; 96 } 97 })()); 98 } else { 99 // Do nothing to fallback to the network. 100 } 101 }); 102 }