Обновить скрипты, импортированные с помощью importScripts в сервис-воркере

У меня есть веб-сайт, на котором есть сервисный работник, например:

// Import a script from another domain
importScripts('https://example.com/script.js')

Предположим, что script.js обновляется каким-то новым кодом, а сервис-воркер активируется из-за push-события (тем временем пользователь больше не посещал мой сайт).

Проверяет ли importScripts наличие обновлений каждый раз при активации сервисного работника или он загружает script.js только один раз при первой установке сервисного работника?

Есть ли способ обновить код сервис-воркера (и, в частности, импортированные скрипты) каждый раз, когда сервис-воркер получает push-сообщение?


person collimarco    schedule 30.06.2016    source источник
comment
Я написал сообщение в блоге с некоторыми советами.   -  person collimarco    schedule 01.05.2017


Ответы (3)


Согласно спецификации сервис-воркеров, скрипты, импортированные через importScripts, сохраняются на карте, когда Service Worker устанавливается/обновляется, а затем повторно используется до нового обновления. На GitHub есть обсуждение с более подробной информацией.

Я не могу придумать способ перезагрузить импортированные сценарии, когда сервисный работник получает push-сообщение. Каков ваш вариант использования?

person Marco Castelluccio    schedule 08.07.2016
comment
Да, к сожалению нет возможности обновить импортированные скрипты. Единственный обходной путь — добавить фиктивный контент в основной код сервис-воркера. Это вариант использования. - person collimarco; 09.07.2016
comment
Да, но даже тогда вы не можете заставить его обновляться при получении push-сообщения, не так ли? Менее уродливый обходной путь — использовать importScriptName- + хэш содержимого импортированного скрипта + .js в качестве имени импортированного скрипта. Таким образом, содержимое сервис-воркера изменится при изменении импортированного скрипта. - person Marco Castelluccio; 09.07.2016
comment
Да, когда приходит push, он проверяет наличие обновлений (я думаю, что последняя проверка обновлений была более чем за 24 часа до этого). Вы не можете легко сгенерировать хэш (импортированный скрипт принадлежит другому домену...), и у людей могут быть статические веб-сайты (или активы). Я также ответил вам в блоге - person collimarco; 10.07.2016
comment
О, ваши клиенты пишут сервис-воркер, я думал, что это решение, похожее на другие сервисы (например, OneSignal), где вы предоставляете сервис-воркер. Кстати, я ответил в блоге. Решение с фиктивным контентом требует, чтобы люди знали, когда импортированные сценарии изменились (поскольку им нужно добавить фиктивный контент, когда контент изменился), не так ли? Вместо этого хеш-решение является автоматическим. Генерация производится на стороне сервера, поэтому не имеет значения, что они принадлежат другому домену. - person Marco Castelluccio; 10.07.2016
comment
Да, это как OneSignal: я думаю, у них точно такая же проблема, если они обновляют свои скрипты. И ИМХО, это проблема генерации хэш-сервера, потому что 1. вы генерируете хеш включенных скриптов каждый раз 2. в противном случае вам также следует реализовать систему кеша, чтобы избежать выполнения HTTP-запросов на стороне сервера и генерации хэша каждый раз. - person collimarco; 11.07.2016
comment
Насколько я помню, с OneSignal они пишут сервис-воркер, а клиенты - нет (что отличается от вашего случая). Обратите внимание: я не говорю, что хэш-решение отличное, я говорю, что это лучше, чем добавление фиктивного контента. - person Marco Castelluccio; 11.07.2016
comment
Нет, это не отличается от моего случая. В этом аспекте OneSignal ведет себя точно так же, как Pushpad. - person collimarco; 11.07.2016

Можно заставить браузер перепроверить/проверить, был ли обновлен код, включенный через importScripts(), путем динамической генерации URL-адреса сервис-воркера — если он меняется каждый час, тогда браузер загрузит и установит «новый» сервис-воркер, включая все импортированные скрипты. .

Следующий код заставит браузер проверять все зависимости каждый час:

const MAXAGE = 3600; // seconds until recheck
const URL = `/sw.js?q=${Math.floor(Date.now() / (MAXAGE * 1000))}`;
navigator.serviceWorker.register(URL);

Демонстрация — откройте JS-консоль и кликните по ней; вы должны увидеть, что импортированный скрипт перезагружается каждые 10 секунд.

(Это не полностью решает вашу проблему (служебный работник обновляется только тогда, когда пользователь посещает страницу, а не при получении push-уведомления), но этого может быть достаточно.)

person mjs    schedule 23.03.2017
comment
Более полный ответ на вопрос о том, как развертывать обновления для сервис-воркеров: stackoverflow.com/a/43471531 - person mjs; 18.04.2017
comment
Это больше не работает в Chrome 71+: chromestatus.com/feature/5748516353736704. - person ofavre; 02.07.2019

В Chrome 68 это можно сделать, установив {updateViaCache: 'none'} при регистрации сервис-воркера. Затем он не использует кеш для содержимого импортированных файлов.

См. полную справку об определении в w3 и Обновления Chrome

person Prashant Singh    schedule 22.03.2019