Service Worker API
==================

Les *service workers* agissent principalement comme des serveurs intermédiaires entre les applications web, le navigateur, et le réseau (lorsque celui-ci est disponible). Ils sont conçus, entre autres, pour permettre la création de fonctionnalités hors ligne, intercepter les requêtes réseau, et agir en conséquence selon que le réseau est disponible ou non, et mettre à jour les fichiers qui sont situés sur le serveur. Ils permettent également d'accéder aux API de notifications *push* et de synchronisation en arrière-plan.

Concepts et utilisation des *service workers*
---------------------------------------------

Un *service worker* est un *worker* manipulé avec des évènements et enregistré relativement à une origine et à un chemin. Il prend la forme d'un fichier JavaScript qui peut contrôler la page web à laquelle il est associé, interceptant et modifiant les requêtes de ressources et de navigation, permettant une gestion fine de la mise en cache des ressources afin de permettre un contrôle complet sur le comportement de votre application dans certains cas (le plus évident étant l'absence de réseau).

Un *service worker* s'exécute dans le contexte d'un *worker* et n'a donc pas accès au DOM. Il s'exécute dans un *thread* différent du *thread* JavaScript principal et n'est donc pas bloquant. Il est conçu pour fonctionner de façon complètement asynchrone. Aussi, les API synchrones comme XHR et *Web Storage* ne peuvent pas être utilisées dans le code d'un *service worker*.

Pour des raisons de sécurité, les *service workers* ne fonctionnent qu'avec le protocole HTTPS. En effet, les connexions HTTP sont susceptibles d'être victimes d'injection de code par attaque du monstre du milieu et l'accès à ces API aggraverait ces attaques.

**Note :** Sur Firefox, les *service workers* ne fonctionnent pas en navigation privée.

**Note :** Sur Firefox, il est possible de tester les *service workers* via HTTP (donc de façon non-sécurisée) en cochant l'option **Activer les Service Workers via HTTP (lorsque la boîte à outils est ouverte)** dans les options des outils de développement.

**Note :** Les *service workers* utilisent les promesses. Ils attendent généralement l'arrivée de réponses auxquelles ils répondront par une action de réussite ou d'échec. L'architecture asynchrone des promesses est idéale pour ce mode de fonctionnement.

### Enregistrement

On commence par enregistrer un *service worker* à l'aide de la méthode `ServiceWorkerContainer.register()`. Si cela fonctionne, le *service worker* sera téléchargé sur le client et tentera les étapes d'installation et d'activation (voir ci-après) pour les URL auxquelles la personne accède pour toute l'origine concernée ou le sous-ensemble qui a été indiqué.

### Téléchargement, installation et activation

À partir de ce point, le *service worker* suivra ce parcours :

1. Téléchargement
2. Installation
3. Activation

Le *service worker* est téléchargé immédiatement lorsque la personne accède pour la première fois à une page/un site contrôlé par un *service worker*.

Ensuite, le *service worker* est mis à jour :

* Lorsque la personne navigue sur une page concernée par la portée du *service worker*.
* Lorsqu'un évènement est déclenché sur le *service worker* et qu'il n'a pas été téléchargé lors des dernières 24 heures.

Une tentative d'installation a lieu lorsque le fichier téléchargé est nouveau, soit parce qu'il est différent (en termes d'octets) du *service worker* actuel, ou parce que c'est la première fois qu'un *service worker* est rencontré pour cette page/ce site.

Si c'est la première fois qu'un *service worker* est disponible, une tentative d'installation a lieu et si elle réussit, il est activé.

S'il y a déjà un *service worker* existant disponible, la nouvelle version est installée en arrière-plan mais n'est pas activée immédiatement. À cet instant, le *service worker* est considéré comme **worker* en attente*. L'activation a lieu dès qu'il n'y a plus de pages chargées qui utilisent encore l'ancien *service worker*. Dès qu'il n'y a plus de pages à charger, le nouveau *service worker* est activé et devient donc le **worker* actif*. L'activation peut être déclenchée plus tôt en utilisant `ServiceWorkerGlobalScope.skipWaiting()` (en-US) et les pages existantes peuvent alors être revendiquées par le *worker* actif avec `Clients.claim()`.

Il est possible d'écouter l'évènement `install` (en-US), cela permet généralement de préparer le *service worker* à être utilisé lorsque cet évènement se déclenche (par exemple en créant un cache avec l'API de stockage et en y plaçant des données qui permettront l'exécution de l'application hors-ligne).

Il existe également un évènement `activate` (en-US) qui est déclenché à l'activation. À ce moment, il est généralement utile de rafraîchir les vieux caches et autres éléments associés à l'ancienne version du *service worker*.

Un *service worker* peut répondre aux requêtes en utilisant l'évènement `FetchEvent`. Les réponses à ces requêtes peuvent être modifiées en utilisant la méthode `FetchEvent.respondWith()` (en-US).

**Note :** Comme les évènements `install`/`activate` peuvent prendre un certain temps à finir, la spécification fournit une méthode `waitUntil()` (en-US). Lorsque celle-ci est appelée sur les évènements `install` ou `activate` avec une promesse, les évènements fonctionnels comme `fetch` et `push` attendront la résolution de la promesse.

Pour un tutoriel complet illustrant comment construire un premier exemple simple fonctionnel, voir le guide Utiliser les *service workers*.

Autres idées de cas d'usage
---------------------------

Les *service workers* sont également conçus pour répondre à ces scénarios :

* Synchronisation de données en arrière-plan
* Réponse à des requêtes de ressource depuis d'autres origines
* Réception de mises à jour de données coûteuses en calcul (par exemple la géolocalisation ou le gyroscope) afin que plusieurs pages puissent utiliser un même ensemble de données
* Compilation et gestion de dépendances côté client à des fins de développement (par exemple CoffeeScript, less, modules CJS/AMD)
* Déclencheurs (*hooks*) pour des services d'arrière-plan
* Gestion de modèles personnalisés selon le motif des URL
* Amélioration des performances, par exemple pour précharger les ressources qui seront probablement nécessaires ensuite (par exemple la prochaine image d'un album que la personne parcourt).

À l'avenir, les *service workers* pourront réaliser d'autres tâches qui rapprocheront la plateforme web des applications natives. D'autres spécifications peuvent déjà exploiter les contextes des *service workers*, par exemple :

* Synchronisation en arrière-plan pour démarrer un *service worker* même lorsqu'il n'y a personne sur le site afin de mettre à jour les caches, etc.
* Réaction aux messages *push* pour démarrer un *service worker* afin d'envoyer un message aux personnes pour leur indiquer que du nouveau contenu est disponible
* Réaction à une date/heure donnée
* Entrée dans une zone géographique donnée.
Interfaces
----------

`Cache`

Représente le stockage pour la paire d'objets `Request` / `Response` mis en cache pendant la vie du *service worker*.

`CacheStorage`

Représente le stockage pour les objets `Cache`. Fournit un répertoire racine pour tous les caches nommés auxquels un *service worker* peut accéder et maintient la liste des noms des objets `Cache` correspondants.

`Client`

Représente la portée d'un client de *service worker*. Un client de *service worker* est un document dans le contexte d'un navigateur ou un `SharedWorker`, contrôlé par un *worker* actif.

`Clients`

Représente un conteneur d'une liste d'objets `Client`. Il s'agit de la méthode principale pour accéder aux clients du *service worker* actif pour l'origine courante.

`ExtendableEvent`

Étend la durée de vie des évènements `install` et `activate` émis sur la portée `ServiceWorkerGlobalScope` (en-US) pendant le cycle de vie d'un *service worker*. Cela permet de s'assurer que les évènements fonctionnels (comme `FetchEvent`) ne sont pas diffusés au *service worker* tant qu'il n'a pas mis à jour ses modèles de base de données, supprimé ses éléments de cache expirés, etc.

`ExtendableMessageEvent`

Un objet représentant l'évènement `message` (en-US) déclenché sur un *service worker* (lorsqu'un message de canal est reçu sur la portée `ServiceWorkerGlobalScope` (en-US) depuis un autre contexte). Permet d'étendre la durée de vie de tels évènements.

`FetchEvent`

Le paramètre passé au gestionnaire d'évènement `onfetch` (en-US). Représente une action de récupération diffusée sur la portée `ServiceWorkerGlobalScope` (en-US) d'un *service worker*. Contient des informations à propos de la requête et de la réponse associé. Fournit une méthode `FetchEvent.respondWith()` (en-US) qui permet de fournir une réponse arbitraire à la page contrôlée.

`InstallEvent` (en-US) 
Obsolète

Non-standard

Le paramètre passé au gestionnaire d'évènement `oninstall` (en-US). Représente une action d'installation diffusée sur la portée `ServiceWorkerGlobalScope` (en-US) d'un *service worker*. Il s'agit d'une interface enfant de `ExtendableEvent` et permet donc de s'assurer que les évènements fonctionnels comme `FetchEvent` ne sont pas diffusés pendant l'installation.

`NavigationPreloadManager` (en-US)

Fournit des méthodes pour gérer le préchargement des ressources avec un *service worker*.

`Navigator.serviceWorker`

Renvoie un objet `ServiceWorkerContainer` qui donne accès à l'enregistrement, la suppression, la mise à jour et la communication avec les objets `ServiceWorker` pour le document associé.

`NotificationEvent`

Le paramètre passé au gestionnaire d'évènement `onnotificationclick` (en-US). L'interface `NotificationEvent` représente un évènement de clic de notification diffusé sur la portée `ServiceWorkerGlobalScope` (en-US) d'un *service worker*.

`ServiceWorker`

Représente un *service worker*. Plusieurs contextes de navigation (par exemple des pages, des *workers*) peuvent être associés au même objet `ServiceWorker`.

`ServiceWorkerContainer`

Fournit un objet représentant le *service worker* comme une unité dans l'écosystème réseau, avec des utilitaires pour enregistrer, décommissionner, mettre à jour des *service workers* et accéder à l'état des *service workers* et de leur enregistrement.

`ServiceWorkerGlobalScope` (en-US)

Représente le contexte global d'exécution d'un *service worker*.

`MessageEvent`

Représente un message envoyé à une portée `ServiceWorkerGlobalScope` (en-US).

`ServiceWorkerRegistration` (en-US)

Représente l'enregistrement d'un *service worker*.

`SyncEvent` (en-US) 
Expérimental

L'interface `SyncEvent` représente une action de synchronisation diffusée sur la portée `ServiceWorkerGlobalScope` (en-US) d'un *service worker*.

`SyncManager` 
Expérimental

Fournit une interface pour enregistrer et écouter les enregistrements de synchronisation.

`WindowClient`

Représente la portée d'un client de *service worker* qui est un document dans le contexte d'un navigateur, contrôlé par un *worker* actif. Il s'agit d'un type particulier d'objet `Client` avec certaines méthodes et propriétés complémentaires.

Spécifications
--------------

| Specification |
| --- |
| Service Workers  |

Voir aussi
----------

* Livre de recettes avec les *service workers*
* Utiliser les *service workers*
* Exemple de code simple avec les *service workers*
* Les *service workers* sont-ils prêts ? (en anglais)
* `Promise`