Я использую инструмент Google workbox-cli
для предварительного кэширования некоторых файлов на моем веб-сайте. Можно ли настроить веб-сервер так, чтобы он возвращал в заголовке ответа HTTP для всех файлов по умолчанию следующее:
cache-control: s-maxage=2592000, max-age=86400, must-revalidate, no-transform, public
Но , пусть веб-браузер использует фолловинг вместо этого только в том случае, если сервисный работник будет предварительно кэшировать файл:
cache-control: s-maxage=2592000, max-age=0, must-revalidate, no-transform, public
Итак, я бы хотел, чтобы работник службы изменил max-age=86400
на max-age=0
в заголовке ответа веб-сервера перед предварительным кэшированием файла. Это заставляет сервисного работника извлекать файлы, которые изменились в соответствии с ревизией в sw.js
, с веб-сервера вместо их извлечения из локального кэша. Все файлы, которые не управляются работником службы, по умолчанию кэшируются на 86400 секунд.
Некоторая справочная информация
В настоящее время я использую следующий скрипт bash для настройки моего sw.js
:
#!/bin/bash
if [ ! -d /tmp/workbox-configuration ]; then
mkdir /tmp/workbox-configuration
fi
cat <<EOF > /tmp/workbox-configuration/workbox-config.js
module.exports = {
"globDirectory": "harp_output/",
"globPatterns": [
EOF
( cd harp_output && find assets de en -type f ! -name "map.js" ! -name "map.json" ! -name "markerclusterer.js" ! -name "modal.js" ! -name "modal-map.html" ! -name "service-worker-registration.js" ! -name "sw-registration.js" ! -path "assets/fonts/*" ! -path "assets/img/*-1x.*" ! -path "assets/img/*-2x.*" ! -path "assets/img/*-3x.*" ! -path "assets/img/maps/*" ! -path "assets/img/video/*_1x1.*" ! -path "assets/img/video/*_4x3.*" ! -path "assets/js/workbox-*" ! -path "assets/videos/*" ! -path "de/4*" ! -path "de/5*" ! -path "en/4*" ! -path "en/5*" | sort | sed 's/^/"/' | sed 's/$/"/' | sed -e '$ ! s/$/,/' >> /tmp/workbox-configuration/workbox-config.js )
cat <<EOF >> /tmp/workbox-configuration/workbox-config.js
],
"swDest": "/tmp/workbox-configuration/sw.js"
};
EOF
workbox generateSW /tmp/workbox-configuration/workbox-config.js
sed -i 's#^importScripts(.*);$#importScripts("/assets/js/workbox-sw.js");\nworkbox.setConfig({modulePathPrefix: "/assets/js/"});#' /tmp/workbox-configuration/sw.js
sed -i 's/index.html"/"/' /tmp/workbox-configuration/sw.js
uglifyjs /tmp/workbox-configuration/sw.js -c -m -o harp_output/sw.js
На моем веб-сервере Nginx по умолчанию поставляется следующий HTTP-заголовок:
more_set_headers "cache-control: s-maxage=2592000, max-age=0, must-revalidate, no-transform, public";
Но если запрашиваемый ресурс не обработан работником службы, значение по умолчанию cache-control
перезаписывается:
location ~ ^/(assets/(data/|fonts/|img/(.*-(1|2|3)x\.|maps/|video/.*_(1x1|4x3)\.)|js/(map|markerclusterer|modal|service-worker-registration|sw-registration)\.js|videos/)|(de|en)/((4|5).*|modal-map\.html)) {
more_set_headers "cache-control: s-maxage=2592000, max-age=86400, must-revalidate, no-transform, public";
}
Проблема с текущим подходом (см. Справочную информацию)
- Я должен отслеживать файлы и обновлять
nginx.conf
соответственно.
max-age=0
используется также для веб-браузеров, которые не поддерживают сервис-работников. Поэтому они запрашивают ресурсы у веб-серверов при каждом посещении страницы.
1-е обновление
Мое желаемое поведение кеширования может быть проиллюстрировано двумя стратегиями workbox . Я хочу, чтобы работник службы показал поведение, описанное ниже в сценариях 1 и 2, хотя cache-control: max-age=86400
доставляется веб-сервером в заголовке HTTP для ресурса (например, default.js
).
Сценарий 1: редакция в sw.js не изменилась
Доступ к веб-странице, файл sw.js
получен с веб-сервера из-за max-age=0
, и веб-браузер заметил, что версия для default.js
не изменилась. В этом случае default.js
извлекается из кэша предварительного кэширования:
Сценарий 2: ревизия в sw.js изменилась
Доступ к веб-странице, файл sw.js
получен с веб-сервера из-за max-age=0
, и веб-браузер заметил, что ревизия default.js
изменилась. В этом случае default.js
извлекается с веб-сервера:
2-е обновление
По сути, желаемая стратегия аналогична стратегии, ориентированной на сеть . Но шаг 2 выполняется только в том случае, если изменилась версия файла в sw.js
.
3-е обновление
Если я не ошибаюсь, уже есть некоторая работа по этому вопросу:
self.addEventListener('install', event => {
event.waitUntil(
caches.open(`static-${version}`)
.then(cache => cache.addAll([
new Request('/styles.css', { cache: 'no-cache' }),
new Request('/script.js', { cache: 'no-cache' })
]))
);
});