Skip to content

Instantly share code, notes, and snippets.

What would you like to do?

Fetch Interception

Fetch Interception, also known as Foreign Fetch and Fallthroug Fetch is a mechanism for service workers to handle fetch requests from clients that are not controlled by the service worker.

The proposed API involves some new API in the service worker spec, as well as some minor modifications to the fetch spec.

New ServiceWorker API

The first part is an API to allow a service worker to explicitly opt-in to intercepting fetch requests. To enabled this, each service worker registration will have an associated list of interception scopes. These scopes should be inside (or equal to) the overall scope of the registration. A new method is added to the activate event to allow setting this list:

[Constructor(DOMString type, optional ExtendableEventInit eventInitDict), Exposed=ServiceWorker]
interface ActivateEvent : ExtendableEvent {
  void interceptFetchRequests(optional (USVString or sequence<USVString>) scopes);

When dispatching an activate event the list of interception scopes is cleared. If the interceptFetchRequests method is subsequently called, the list of interception scopes is set to the passed scope or scopes, or set to the scope of the registration is no explicit scopes are passed.

Another (maybe cleaner) option would be to have the list of interception scopes stored on a per service worker base. In that case it could be the install event instead of the activate event that would have the method to register to receive these events.

A couple of new algorithms should also be added to the service worker spec:

Match Service Worker Registration for Fetch Interception

`requestURL`, an absolute URL
`registration`, a service worker registration
  1. Run the following steps atomically.
  2. Let registration be the result of running the Match Service Worker Registration algorithm with requestURL as parameter.
  3. If registration is null, return null.
  4. Let requestURLString be the serialized requestURL
  5. For each [[scope]] in the registrations interception scopes:
  6. If requestURLString starts with [[scope]], then: 1. Return registration
  7. Return null.

This first finds a potential service worker registration candidate by checking its scope, and then checks if the interception scopes of that service worker include the request URL. I think this behavior is more sensible than the other option, which would be to instead try to find the service worker registration which has the longest interception scope that matches the request.

Thes two would be different in the case where SW1 has scope /scope with interception scope /scope/nested/foo while SW2 has scope /scope/nested and interception scope /scope/nested. In the algorithm as described requests for /scope/nested/foo/bar would be handled by SW2, while the other option would be that this should behandled by SW1.

Handle Fetch Interception

`request`, a request
`respone`, a service worker registration

Not in formal algorithm form yet, but this would do something like the following:

  1. Look up registration for the request using Match Service Worker Registration for Fetch Interception algorithm
  2. If requests client is a service worker, make sure it isn't a worker for the same SW registration (or maybe the entire origin?)
  3. Create a FetchEvent instance for the request (or maybe a modified version of the request to hide data we don't want to expose to the SW). This FetchEvent will have a null client.
  4. Dispatch 'fetch' FetchEvent to active worker. Or maybe this should be dispatched as some other event type.

Modifications to Fetch

Add a new step to the HTTP fetch algorithm between step 2 and 3, something like this:

2½. If response is null, and the request's skip-service-worker flag is unset run these substeps:

  1. Set response to the result of invoking Handle Fetch Interception for request.
  2. In some cases return a network error.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment