X

Создаём офлайн-страницу для своего сайта

Можно долго убеждать себя, что ваш хостинг-провайдер самый лучший и ваш сайт всегда онлайн. Но всё равно вы не убережёте себя от вездесущего «закона подлости» или правила Мёрфи, которое гласит:

Всё, что может пойти не так, пойдёт не так.

Об этом помнят, когда красиво оформляют страницу 404. У разработчиков нет цели показать её пользователям намеренно. Просто они понимают, что, несмотря ни на что, кто-нибудь когда-нибудь на неё попадёт.

Но бывает так, что ваша красиво свёрстанная страница 404 бесполезна. Что, если случатся перебои в работе сервера? А что, если у пользователя пропадёт сеть? Всё это может произойти и обязательно произойдёт. Почему бы не позабавить пользователя во время этих событий?

Для этого можно использовать технологию Service Worker, которая поможет пойти против закона Мёрфи в случае сбоя сети или сервера. После установки worker сможет перехватывать любые запросы к вашему домену. Если что-то пойдёт не так с запросом (что неизбежно), то можно предоставить браузеру инструкции на этот случай. Service Worker — это возможность обернуть серверный негатив в небольшой браузерный позитив. Если у вас страница 404 уже красиво оформлена, то почему бы не добавить к ней не менее привлекательную офлайн-страницу?

Перейдите наконец на HTTPS

Сначала переведите свой сайт на HTTPS, если до сих пор не сделали этого. В противном случае вы не сможете использовать Service Worker. Хотя есть небольшая оговорка — локально worker’ы будут работать нормально и без HTTPS, но в продакшене этот протокол обязателен.

Смотрите также: Как установить бесплатный SSL-сертификат для своего сайта

Сделайте офлайн-страницу

Предположим, что ваш сайт уже использует HTTPS, в таком случае можем перейти к созданию офлайн-страницы. Сделайте её настолько серьёзной или причудливой, насколько это вписывается в рамки бренда. Если, предположим, ваш сайт посвящён ресторанному бизнесу, вы могли бы добавить номер и адрес заведения. Для вдохновения посмотрите на офлайн-страницу прошлогодней конференции «Амперсанд».

Также не забудьте поместить офлайн-страницу на подходящий URL, например, /offline.html

Позаботьтесь о предварительном кешировании офлайн-страницы

Создайте файл serviceworker.js. Этот файл будет содержать сценарий, к которому браузер будет обращаться при срабатывании определённых событий. Первое из них, которое нужно обработать — действия, когда service worker установлен на устройстве пользователя. Когда это происходит, событие install удаляется. Вы можете обработать это событие с помощью метода addEventListener():

addEventListener('install', installEvent => {
// ваши инструкции здесь
}); // конец метода addEventListener

Убедитесь, что ваша офлайн-страница сохраняется в кеше. Можете использовать Cache API для сохранения. Можете сохранить сколько угодно страниц и назвать их как захочется. В этом примере назовём закешированную страницу Johny, так в коде на неё можно ссылаться используя JohnyCache:

addEventListener('install', installEvent => {
  installEvent.waitUntil(
    caches.open('Johnny')
    .then( JohnnyCache => {
      JohnnyCache.addAll([
       '/offline.html'
      ]); // конец addAll
    }) // конец open.then
  ); // конец waitUntil
}); // конец addEventListener

Скорее всего ваша офлайн-страница связана с CSS-файлом, а также, вероятно, с парой картинок или даже с JavaScript-файлами. Это всё можно закешировать.

addEventListener('install', installEvent => {
  installEvent.waitUntil(
    caches.open('Johnny')
    .then( JohnnyCache => {
      JohnnyCache.addAll([
       '/offline.html',
       '/path/to/stylesheet.css',
       '/path/to/javascript.js',
           '/path/to/image.jpg'
      ]); // конец addAll
    }) // конец open.then
  ); // конец waitUntil
}); // конец addEventListener

Убедитесь, что все URL-адреса верны. Если хотя бы один из URL’ов не будет получен, то все остальные элементы не закешируются.

Перехват запросов

Следующее событие для обработки — fetch. Это, вероятно, наиболее сильная и в то же время страшная функция service worker’а. После установки fetch worker прячется на устройстве пользователя, ожидая появления любых запросов на ваш сайт. Каждый раз, когда пользователь запрашивает веб-страницу, CSS-файл или изображение, будет срабатывать fetch. Вы можете предопределить обработку этого события:

addEventListener('fetch', fetchEvent => {
// вам решать, что произойдёт дальше
}); // конец addEventListener

Напишем довольно консервативный скрипт со следующей логикой:

  • запрос файла;
  • попытка извлечь его из сети;
  • если не сработало, попробовать найти в кеше,
  • если не сработало и это был запрос веб-страницы, то…
  • покажите оффлайн-страницу.

Вот как это выглядит в JavaScript:

// Всегда, когда файл запрашивается
addEventListener('fetch', fetchEvent => {
  const request = fetchEvent.request;
  fetchEvent.respondWith(
    // Сначала попытка запросить его из Сети
    fetch(request)
    .then( responseFromFetch => {
      return responseFromFetch;
    }) // конец fetch.then
    // Если не сработало, то...
    .catch( fetchError => {
      // пытаемся найти в кеше
      caches.match(request)
      .then( responseFromCache => {
        if (responseFromCache) {
         return responseFromCache;
       // если не сработало и...
       } else {
         // это запрос к веб-странице, то...
         if (request.headers.get('Accept').includes('text/html')) {
           // покажите вашу офлайн-страницу
           return caches.match('/offline.html');
         } // 1конец if
       } // конец if/else
     }) // конец match.then
   }) // конец fetch.catch
  ); // конец respondWith
}); // конец addEventListener

Подключение сценария service worker’а

Вы можете добавить сценарий worker’а в файл /serviceworker.js, но всё равно нужно указать браузеру, где этот сценарий искать. Это делается с помощью JavaScript. Поместите следующие строчки кода в уже существующий JS-файл, который вызываете на каждой странице сайта, или просто добавьте их через тег script в конце HTML каждой страницы.

if (navigator.serviceWorker) {
  navigator.serviceWorker.register('/serviceworker.js');
}

Это сообщает браузеру о начале установки service worker’а, но предварительно убедившись, что браузер понимает, о чём идёт речь. Не забывайте отлавливать исключения.

Вероятно, у вас есть несколько JS-файлов в папке /assets/js/, куда вы хотели бы добавить и serviceworker.js. Не делайте этого. В таком случае worker сможет обрабатывать запросы, сформированные только для файлов в папке /assets/js/. Поместите скрипт в корневой каталог, так можете быть уверены, что любой запрос будет перехвачен.

Что дальше?

Отлично, теперь вы можете быть уверены, что если пользователи не могут подключиться к сайту, то они увидят не банальное сообщение об ошибке, а крутую офлайн-страницу. Вы сделали небольшой шаг против закона Мёрфи.

Вы можете сделать многое другое с worker’ами. Что, если каждый раз, когда вызывается страница, она могла бы потом сохраняться копией в кеше? Затем, когда пользователь перейдёт на неё, находясь не в сети, вы сможете ему её показать.

Или что, если вместо того, чтобы обратиться к серверу, вы проверили бы наличие файла в кеше. Можно выводить кешированную версию, которая явно быстрее и при этом обновлять её в фоновом режиме. Это может быть хорошим вариантом для сайта с изображениями.

Вариантов много, поэтому сложность заключается не в написании кода, а в определении алгоритма. Когда вы проработаете алгоритм, то можете спокойно переводить его в код на JavaScript.

Перевод статьи «Mistletoe Offlines»

Евгений Туренко

Также рекомендуем:

Рубрика: Переводы
Темы: Веб-разработка