наш блог
Скрипт-субмарина: основы стремительного погружения в Service Worker

Service Worker – замечательная технология, с помощью которой можно расширить возможности твоего сайта. Она представляет собой почти обычный javascript-файл. Я написал «почти» потому, что в нем нет привычного доступа к объекту document и window.
Кстати, это некоторые из его возможностей:
-
Кэширование данных сайта для увеличения скорости повторной загрузки;
-
Перехват и модифицирование запросов браузера;
-
Работа с push-уведомлениями;
-
Progressive Web Application.
Тем не менее существует и ряд нюансов, ограничивающих работу Service Worker. Во-первых, это относительно новая технология, которая «не уживается» с устаревшими браузерами. Во-вторых, Service Worker не работает в режиме инкогнито. А главное, в целях обеспечения безопасности технология взаимодействует только с протоколом HTTPS. Единственное исключение – разработка на localhost.
По сути, Service Worker – это посредник между браузером и сервером. Впрочем, довольно теории. Перейдем к коду. Html-файл рассматриваемой мною страницы будет выглядеть так:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>SW deep dive</title>
</head>
<body>
<h1>SW deep dive!</h1>
<script src="script.js"></script>
</body>
</html>
Страница может быть любой. Все, что требуется – подключить javascript-файл, в котором нужно будет зарегистрировать Service Worker.
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js').then(
registration => {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
},
err => {
console.log('ServiceWorker registration failed: ', err);
}
);
});
В коде, который показан выше, происходит регистрация Service Worker. Так и начинается его жизненный цикл. Но обо всем по порядку. В первую очередь нужно проверить, есть ли в глобальном объекте navigator объект serviceWorker. Это необходимо для того, чтобы исключить возможные ошибки в устаревших браузерах.
Далее нужно вызвать метод register(), в который первым параметром указывается путь к файлу Service Worker. Важно запомнить, что делается это относительно корня приложения, а не местоположения в проекте. А значит, sw.js будет находиться по адресу «https://my_site.com/sw.js». Также есть возможность указать рамки действия Service Worker, что достигается передачей объекта опций с полем scope во второй параметр метода регистрации:
navigator.serviceWorker.register('/sw.js', {scope: '/some_scope'})
Теперь Service Worker будет контролировать все страницы с адресом, который начинается с «https://my_site.com/some_scope». Если не указывать scope, то он установится по умолчанию. Это и будет корень сайта. Файл sw.js будет выглядеть так:
self.addEventListener('install', function(event) {
console.log('installed!', event)
});
self.addEventListener('activate', function(event) {
console.log('activated!', event)
});
self.addEventListener('fetch', function(event) {
console.log('fetch', event)
});
Первым делом, после регистрации Service Worker, возникнет событие install. Зачастую в его обработчике кешируют необходимые файлы. Далее «включается» обработчик события activate. Оно может возникнуть в двух ситуациях. Либо во время установки нового Service Worker. Либо если его файл изменился и отличается от ранее установленного. В последнем варианте новый Service Worker переходит в состояние wating, а старый продолжает контролировать сайт до того момента, пока не будут закрыты все страницы.
И наконец, событие fetch. Его обработчик вызывается после установки Service Worker – в момент, когда пользователь обновляет страницу или переходит на другую. В этом обработчике можно перехватывать уходящие запросы и каким-то образом модифицировать их. А также вместо запроса «отдавать» на сервер данные из кэша.
Для запуска рассматриваемого примера потребуется виртуальный сервер. Я буду использовать http-server. Установить его можно командой «npm i-g http-server». Но только тогда, когда уже имеется установленный node.js. Запускаю сайт командой «http-server» в корне проекта. И если все условия установки Service Worker соблюдены, то в консоле браузера появляется строка: «ServiceWorker registration successful with scope: http://localhost:8080/». Она и будет свидетельствовать об успешной установке.
Юрий Кизилов, компания Craft Group