ServiceWorker handling fetch events to URLs outside scope
Asked Answered
A

1

5

My site registers a ServiceWorker which is scoped to only URLs beginning with /sw/....

 /**
  * Register the Service Worker.
  */
 if ('serviceWorker' in navigator) {
     navigator.serviceWorker
         .register('{{ URL::asset('sw/serviceworker.js') }}', {scope: './sw/'})
         .then(registration => {
             console.log("SW registered. Scope: ", registration.scope);
         }).catch(err => { console.error("SW Register failed: ", err); });
}

One of the pages inside the /sw/... path performs a fetch to the server to see if connection to the server is available. The address it fetches is /ping, a simple page that returns some JSON. Note the address /ping/ is not inside the /sw/... path).

// Sample of the bit inside my promise that checks for the server
// this is the request that is being cached

fetch('/ping')
    .then(function(response) {

        if (response.status == 200) {
            console.log('%c Server available! ', 'background: #20c997; color: #000');
        }

    })
    .catch(function(err) {
        console.log('fetch failed! ', err);
    });

Yet the browser clearly shows the serviceWorker intercepting the request to /ping.

From the Google Chrome Dev Console:

▶ Fetching http://127.0.0.1:8000/ping Request {method: "GET", url: "http://127.0.0.1:8000/ping", headers: Headers, referrer: "http://127.0.0.1:8000/sw/create", referrerPolicy: "no-referrer-when-downgrade", …} serviceworker.js:105 
▶ Fetched over network http://127.0.0.1:8000/ping:  Response {type: "basic", url: "http://127.0.0.1:8000/ping", redirected: false, status: 200, ok: true, …} 

This is not doing what I expect because I only want the ServiceWorker to intercept requests to addresses starting with /sw/...

Is there somewhere in the spec or intended behaviour of ServiceWorkers that says it can cache the responses to fetch events made by pages in-scope, even if the address it is hitting is out of scope?

Alleman answered 3/1, 2019 at 17:32 Comment(0)
A
7

Answering my own question...

Yes, this is intended behaviour. Scope is not determined by the address that the fetch is being made to, but the address of the page making the request.

The key word is "from" in this quote from Google's Guide:

...it will handle fetch and message events that occur when a network request or message is made from your page.

So if the JavaScript on /sw/page1.html makes a fetch() request to /ping then this is considered "in scope" by the ServiceWorker because the page sending the request starts with /sw/....

Scope also includes the original request made by the browser to fetch the page. So if the browser attempts to navigate to pages starting with /sw/... and there is a ServiceWorker registered then it will handle that request.

Alleman answered 10/1, 2019 at 16:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.