Как использовать ServiceWorker без отдельного JS-файла?

Мы создаем сервис-воркеров

navigator.serviceWorker.register('sw.js', { scope: '/' });

Мы можем создать новый Workers без внешнего файла, подобного этому,

var worker = function() { console.log('worker called'); };
var blob = new Blob( [ '(' , worker.toString() , ')()' ], {
    type: 'application/javascript'
});
var bloburl = URL.createObjectURL( blob );
var w = new Worker(bloburl);

При использовании большого двоичного объекта для создания Service Workers мы получим Security Error, так как bloburl будет blob:chrome-extension..., а источник не будет поддерживаться Service Workers.

Можно ли создать работника службы без внешнего файла и использовать область действия как /?


person Boopathi Rajaa    schedule 16.01.2015    source источник


Ответы (2)


Я бы настоятельно рекомендовал не пытаться найти способ обойти требование, чтобы код реализации сервис-воркера находился в отдельном файле. В жизненном цикле сервис-воркера очень важен обновления, который зависит в вашем браузере возможность периодически получать ваш зарегистрированный ресурс JavaScript сервисного работника и выполнять побайтовое сравнение, чтобы увидеть, изменилось ли что-нибудь.

Если что-то изменилось в вашем коде сервис-воркера, то новый код будет считаться installing сервис-воркером, а старый код сервис-воркера в конечном итоге будет считаться redundant сервис-воркером, как только все страницы со старым кодом будут зарегистрированы и выгружены/ закрыто.

Хотя поначалу это немного сложно понять, важно понимать и использовать различные состояния/события жизненного цикла сервис-воркера, если вы беспокоитесь об управлении кешем. Если бы не эта логика обновления, после того, как вы один раз зарегистрировали сервис-воркера для данной области, он бы никогда не отказался от управления, и вы бы застряли, если бы у вас была ошибка в вашем коде/нужно было добавить новую функциональность.

person Jeff Posnick    schedule 16.01.2015
comment
Может быть, закодировать весь serviceWorker в строке BASE64? - person Sandro Paganotti; 21.01.2015
comment
Я пробовал все возможные способы, работал только с использованием filesystem: URL-адресов, но он перестал работать. Это печально, потому что предполагает то, что сказал Джефф, и строго запрещает разработчикам создавать Internet Explorer 6 на основе JavaScript, то есть: приложения без автоматического обновления. Да ладно, сейчас 2015 год, а в Tor нет автообновления. Вместо этого у него ручной (надежнее ли? не знаю). Почему мы не можем сделать то же самое в JS? Дружественный интерфейс? Я не уверен в этом: отключение расширения Firefox и автоматического обновления приложений Android — это просто флажок. - person Gustavo Rodrigues; 25.03.2015

Один хакерский способ - использовать один и тот же файл javascript, понимать контекст и действовать как ServiceWorker, а также как тот, кто его вызывает.

HTML

<script src="main.js"></script>

main.js

if(!this.document) {
    self.addEventListener('install', function(e) {
        console.log('service worker installation');
    });
} else {
    navigator.serviceWorker.register('main.js')
}

Чтобы не хранить это как большой файл main.js, мы могли бы использовать

if(!this.document) {
    //service worker js
    importScripts('sw.js');
else {
    //loadscript document.js by injecting a script tag
}

Но, возможно, лучше вернуться к использованию отдельного файла sw.js для сервис-воркера. Это было бы полезно, если бы кто-то хотел иметь единую точку входа в скрипты.

person Boopathi Rajaa    schedule 16.01.2015
comment
Я бы не рекомендовал этот подход, так как он нарушил бы логику запуска потока update при изменении кода работника службы. - person Jeff Posnick; 16.01.2015
comment
@ jeff-posnick, можете ли вы уточнить (помимо вашего принятого ответа), как это противоречит логике? Похоже, что ServiceWorker будет переустанавливаться всякий раз, когда редактируется main.js, что позволяет запускать повторную установку извне, но не предотвращает обновления. - person Matthew Cook; 06.08.2015