Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(http): Add pages for Service Workers #37230

Merged
merged 11 commits into from
Dec 19, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ This could be for the following reasons:
- The path to your service worker file is not written correctly — it needs to be written relative to the origin, not your app's root directory. In our example, the worker is at `https://bncb2v.csb.app/sw.js`, and the app's root is `https://bncb2v.csb.app/`. But the path needs to be written as `/sw.js`.
- It is also not allowed to point to a service worker of a different origin than that of your app.
- The service worker will only catch requests from clients under the service worker's scope.
- The max scope for a service worker is the location of the worker (in other words if the script `sw.js` is located in `/js/sw.js`, it can only control URLs under `/js/` by default). A list of max scopes for that worker can be specified with the `Service-Worker-Allowed` header.
- The max scope for a service worker is the location of the worker (in other words if the script `sw.js` is located in `/js/sw.js`, it can only control URLs under `/js/` by default). A list of max scopes for that worker can be specified with the {{HTTPHeader("Service-Worker-Allowed")}} header.
bsmth marked this conversation as resolved.
Show resolved Hide resolved
- In Firefox, Service Worker APIs are hidden and cannot be used when the user is in [private browsing mode](https://bugzil.la/1320796), or when history is disabled, or if cookies are cleared when Firefox is closed.
- In Chrome, registration fails when the "Block all cookies (not recommended)" option is enabled.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this into BCD?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good 👍🏻

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see f6de952


Expand Down Expand Up @@ -452,3 +452,4 @@ self.addEventListener("activate", (event) => {

- [Promises](/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
- [Using web workers](/en-US/docs/Web/API/Web_Workers_API/Using_web_workers)
- {{HTTPHeader("Service-Worker-Allowed")}} HTTP header
30 changes: 15 additions & 15 deletions files/en-us/web/api/serviceworkercontainer/register/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ register(scriptURL, options)
- : A string representing a URL that defines a service worker's registration scope; that is, what range of URLs a service worker can control.

This is usually specified as a URL that is relative to the base URL of the site (e.g. `/some/path/`), so that the resolved scope is the same irrespective of what page the registration code is called from.
By default, the `scope` value for a service worker registration is set to the directory where the service worker script is located (by resolving `./` against `scriptURL`).
The default `scope` for a service worker registration is the directory where the service worker script is located (resolving `./` against `scriptURL`).

The scope must specify documents that are in the same directory or more deeply nested than the service worker (if you need a broader scope, this can be permitted via the HTTP `Service-Worker-Allowed` header).

See the [Examples](#examples) section for more information on how it works.
The scope should be used to specify documents that are in the same directory or more deeply nested than the service worker.
If you need a broader scope, this can be permitted via the HTTP {{HTTPHeader("Service-Worker-Allowed")}} header.
See the [Examples](#examples) section for information on broadening the default scope of a service worker.

- `type`

Expand Down Expand Up @@ -95,11 +95,11 @@ A {{jsxref("Promise")}} that resolves with a {{domxref("ServiceWorkerRegistratio

## Examples

The examples described here should be taken together to get a better understanding of how service workers scope applies to a page.
The examples below should be read together to understand how service worker scope applies to a page.

### Register a service worker with default scope

The following example uses the default value of `scope` (by omitting it), which sets it to be the same location as the script URL.
The following example uses the default value of `scope` by omitting it, which sets it to be the same location as the script URL.

Suppose the service worker code is at `example.com/sw.js`, and the registration code at `example.com/index.html`.
The service worker code will control `example.com/index.html`, as well as pages underneath it, like `example.com/product/description.html`.
Expand All @@ -121,13 +121,13 @@ if ("serviceWorker" in navigator) {
}
```

Note that we have registered the scriptURL relative to the site root rather than the current page.
Note that we have registered the `scriptURL` relative to the site root rather than the current page.
This allows the same registration code to be used from any page.

### Register a service worker with an explicit default scope

The code below is almost identical, except we have specified the scope explicitly using `{ scope: "/" }`.
Again, we've specified the scope as site-relative so the same registration code can be used from anywhere in the site.
We've specified the scope as site-relative so the same registration code can be used from anywhere in the site.

```js
if ("serviceWorker" in navigator) {
Expand All @@ -145,15 +145,15 @@ if ("serviceWorker" in navigator) {
}
```

This scope happens to be the same as the default scope, so the registration applies to exactly the same pages as the example above.
This scope is the same as the default scope, so the registration applies to exactly the same pages as the previous example.
Note that if we were to run this code after the previous example, browsers should recognize that we're updating an existing registration rather than a new one.

### Register a service worker using page-relative URLs

There is nothing to stop you from using page-relative URLs except that this makes it harder to move your pages around, and it is easy to accidentally create unwanted registrations if you do so.

In this example the service worker code is at `example.com/product/sw.js`, and the registration code at `example.com/product/description.html`.
We're using URLs that are relative to the current directory for the scriptURL and the scope, where the current directory is the base URL of the page that is calling `register()` (`example.com/product/`).
We're using URLs that are relative to the current directory for the `scriptURL` and the `scope`, where the current directory is the base URL of the page that is calling `register()` (`example.com/product/`).
The service worker applies to resources under `example.com/product/`.

```js
Expand All @@ -174,9 +174,8 @@ if ("serviceWorker" in navigator) {

### Using Service-Worker-Allowed to increase service worker scope

There is frequent confusion surrounding the meaning and use of _scope_.
A service worker can't have a scope broader than its own location, unless the server specifies a broader maximum scope in a [Service-Worker-Allowed](https://w3c.github.io/ServiceWorker/#service-worker-allowed) header on the service worker script.
Therefore you should use the `scope` option when you need a _narrower_ scope than the default.
A service worker can't have a scope broader than its own location, unless the server specifies a broader maximum scope in a {{HTTPHeader("Service-Worker-Allowed")}} header on the service worker script.
Use the `scope` option when you need a _narrower_ scope than the default.

The following code, if included in `example.com/index.html`, at the root of a site, would only apply to resources under `example.com/product`.

Expand All @@ -196,8 +195,8 @@ if ("serviceWorker" in navigator) {
}
```

As noted above, servers can change the default maximum scope by setting the `Service-Worker-Allowed` header on the service worker script.
In this case, the `scope` option should specify a scope narrower than the header value, but potentially larger than the service worker's location.
As noted above, servers can change the default scope by setting the `Service-Worker-Allowed` header on the service worker script.
This allows the `scope` option to be set outside the path defined by the service worker's location.

The following code, if included in `example.com/product/index.html`, would apply to all resources under `example.com` if the server set the `Service-Worker-Allowed` header to `/` or `https://example.com/` when serving `sw.js`. If the server doesn't set the header, the service worker registration will fail, as the requested `scope` is too broad.

Expand Down Expand Up @@ -233,3 +232,4 @@ if ("serviceWorker" in navigator) {
- [ServiceWorkerRegistration: `unregister()` method](/en-US/docs/Web/API/ServiceWorkerRegistration/unregister)
- [Service worker API](/en-US/docs/Web/API/Service_Worker_API)
- [Using service workers](/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers)
- {{HTTPHeader("Service-Worker-Allowed")}} HTTP header
5 changes: 4 additions & 1 deletion files/en-us/web/http/headers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,10 @@ Headers used by the [WebSockets API](/en-US/docs/Web/API/WebSockets_API) in the
- : Indicates how long the user agent should wait before making a follow-up request.
- {{HTTPHeader("Server-Timing")}}
- : Communicates one or more metrics and descriptions for the given request-response cycle.
- `Service-Worker-Allowed`
- {{HTTPHeader("Service-Worker")}}
- : Included in fetches for a service worker's script resource.
This header helps administrators log service worker script requests for monitoring purposes.
- {{HTTPHeader("Service-Worker-Allowed")}}
- : Used to remove the [path restriction](/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#why_is_my_service_worker_failing_to_register) by including this header [in the response of the Service Worker script](https://w3c.github.io/ServiceWorker/#service-worker-script-response).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update this description to, in particular, remove the spec link. Should be something along the lines of "Use allow a service worker to be registered to a broader scope that allowed by its URL location ..."

- {{HTTPHeader("SourceMap")}}
- : Links to a {{Glossary("source map")}} so that debuggers can step through original source code instead of generated or transformed code.
Expand Down
84 changes: 84 additions & 0 deletions files/en-us/web/http/headers/service-worker-allowed/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
title: Service-Worker-Allowed
slug: Web/HTTP/Headers/Service-Worker-Allowed
page-type: http-header
browser-compat: http.headers.Service-Worker-Allowed
---

{{HTTPSidebar}}

The HTTP **`Service-Worker-Allowed`** {{Glossary("response header")}} is used to broaden the path restriction for a service worker's default `scope`.

By default, the [`scope`](/en-US/docs/Web/API/ServiceWorkerContainer/register#scope) for a service worker registration is the directory where the service worker script is located.
For example, if the script `sw.js` is located in `/js/sw.js`, it can only control URLs under `/js/` by default.
Servers can use the `Service-Worker-Allowed` header to allow a service worker to control URLs outside of its own directory.

A service worker intercepts all network requests within its scope, so you should avoid using overly-broad scopes unless necessary.

<table class="properties">
<tbody>
<tr>
<th scope="row">Header type</th>
<td>{{Glossary("Response header")}}</td>
</tr>
<tr>
<th scope="row">{{Glossary("Forbidden header name")}}</th>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true, we might want to discuss whether we want this table row on response headers at all, seeing as it's always No except for Set-Cookie.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does anyone else agree that we should move the Forbidden XYZ lists from the the glossary into the HTTP documentation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, great idea, I think it might be time to do that

<td>No</td>
</tr>
</tbody>
</table>

## Syntax

```http
Service-Worker-Allowed: <scope>
```

## Directives

- `<scope>`
- : A string representing a URL that defines a service worker's registration scope; that is, what range of URLs a service worker can control.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is true, but perhaps we should capture that it is the top level directory?

Suggested change
- : A string representing a URL that defines a service worker's registration scope; that is, what range of URLs a service worker can control.
- : A string representing a URL that defines a service worker's registration scope; that is, a URL that defines the root path of the range of URLs that a service worker can control.

Copy link
Collaborator

@hamishwillee hamishwillee Dec 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition, what counts as a valid URL? Relative URLs? Absolute URLs? What if there are query parameters? What if this is a file? Is it relative to the site root?

Usually these kinds of headers take either absolute or relative URLs (to site root), and query parameters are stripped along with any credentials and file names. But sometimes the rules are different, so we should say.


## Examples

### Using Service-Worker-Allowed to broaden service worker scope

The JavaScript example below is included in `example.com/product/index.html`, and attempts to [register](/en-US/docs/Web/API/ServiceWorkerContainer/register) a service worker with a scope that applies to all resources under `example.com/`.

```js
navigator.serviceWorker.register("./sw.js", { scope: "/" }).then(
(registration) => {
console.log("Install succeeded, scoped to '/'", registration);
},
(error) => {
console.error(`Service worker registration failed: ${error}`);
},
);
```

The HTTP response to the service worker's script resource request (`./sw.js`) includes the `Service-Worker-Allowed` header set to `/`:

```http
HTTP/1.1 200 OK
Date: Mon, 16 Dec 2024 14:37:20 GMT
Service-Worker-Allowed: /

// sw.js contents…
```

If the server doesn't set the header, the service worker registration will fail, as the `scope` option (`{ scope: "/" }`) requests a scope broader than the directory where the service worker script is located (`/product/sw.js`).

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- {{HTTPHeader("Service-Worker")}} header
- [Service worker API](/en-US/docs/Web/API/Service_Worker_API)
- {{domxref("ServiceWorkerRegistration")}}
bsmth marked this conversation as resolved.
Show resolved Hide resolved
- [Why is my service worker failing to register](/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#why_is_my_service_worker_failing_to_register) in _Using Service Workers_.
49 changes: 49 additions & 0 deletions files/en-us/web/http/headers/service-worker/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: Service-Worker
slug: Web/HTTP/Headers/Service-Worker
page-type: http-header
browser-compat: http.headers.Service-Worker
---

{{HTTPSidebar}}

The HTTP **`Service-Worker`** {{Glossary("request header")}} is included in fetches for a service worker's script resource.
This header helps administrators log service worker script requests for monitoring purposes.

<table class="properties">
<tbody>
<tr>
<th scope="row">Header type</th>
<td>{{Glossary("Request header")}}</td>
</tr>
<tr>
<th scope="row">{{Glossary("Forbidden header name")}}</th>
<td>No</td>
</tr>
</tbody>
</table>

## Syntax

```http
Service-Worker: script
```

## Directives

- `script`
- : A value indicating that this is a script.
bsmth marked this conversation as resolved.
Show resolved Hide resolved
This is the only allowed directive for this header.

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- {{HTTPHeader("Service-Worker-Allowed")}} header
- [Service worker API](/en-US/docs/Web/API/Service_Worker_API)
Loading