Как мне определить в выборке работника службы, что запрос относится к start_url манифеста?

#javascript #service-worker #progressive-web-apps #fetch-api

#javascript #service-worker #progressive-web-apps #fetch-api

Вопрос:

У меня есть PWA, в котором есть a manifest.json с a start_url .

У меня есть service worker с fetch событием, которое кэширует только определенные запросы. Это делается в service worker путем переопределения ответа на прокси из кэша (машинопись для ясности):

 self.addEventListener('fetch', (event: FetchEvent) => {
    // This MUST be synchronous until respondWith is called

    const cache = isCachable(event.request);
    if (!isCachable)
        return; // Don't proxy, let the network request continue

    // Kick off a promise to check the cache, and clone/cache the response otherwise
    const proxy: Promise<Response> = cacheResponse(event);

    event.respondWith(proxy);
}
  

Я хочу кэшировать start_url , что означает isCachable , что выше должно быть указано, что значение start_url является запрашиваемым относительным маршрутом.

Я могу загрузить manifest.json в SW, но это кажется действительно неуклюжим. Я могу жестко запрограммировать значения в SW, но затем мне нужно обновить два места, если конфигурация изменится.

В fetch обработчике event.request.url является абсолютным, но start_url относительным к manifest.json — так, например, я мог бы иметь:

  • manifest.json : { "start_url": "appshell" ... }
  • Веб-сайт развертывается на www.example.com/folder/ (но может быть развернут на sub.example.com или www.example.com/a/b или что-то еще)
  • Онлайн-пользователь посещает сайт, либо посещает все, либо устанавливает кэш скрипта напрямую.
  • Позже тот же пользователь переходит в автономный режим.
  • Приведенная выше выборка срабатывает с event.request.url === 'www.example.com/folder/appshell'
  • Мне нужно isCachable , чтобы функция могла указывать, что ресурс должен кэшироваться синхронно. Ему необходимо определить, что www.example.com/folder/appshell это appshell (разрешить относительную ссылку), и это appshell установлено как start_url (прочитать манифест).

Очевидно, что все это может быть жестко запрограммировано. Однако для каждого PWA требуется ответ из кэша start_url , поэтому это не может быть новой проблемой. Прежде чем я изобрету колесо, есть ли лучший способ или что-то, чего мне не хватает?

Итак…

  • Учитывая, что работникам службы нужен манифест, есть ли хороший способ получить конфигурацию манифеста в воркере?
  • Есть ли способ разрешить относительную ссылку для сравнения с манифестом?

Комментарии:

1. Вы говорите о манифесте веб-приложения, верно? Не о расширении?

2. И ваш вопрос касается только разрешения относительных путей? Если да, вы хотите разрешить его относительно SW или из документа, который отправил запрос?

3. @Kaiido есть только один manifest.json , который применяется к работникам службы. Да, это прогрессивное веб-приложение, а не расширение для браузера. start_url Относится к манифесту. event.request.url Переданный fetch обработчику в service worker является абсолютным, кэш в service worker относится к service worker. Мне не нужно искать относительные ссылки где-либо еще, этот вопрос касается только конкретного случая начального URL-адреса, который должен быть кэширован service worker.

4. Тогда почему вы продолжаете использовать тег, предназначенный для веб-расширений? И отредактированная вами ссылка на документацию устарела, с тех пор появилось новое расширение. webmanifest был официально оформлен.

5. @Kaiido потому что это конкретно вопрос о manifest.json , а контекст service worker гораздо более понятен, чем контекст расширения (угадайте, какой из них является лучшим в поиске?), И оба являются вариантами одного и того же.

Ответ №1:

Я понял, как это сделать, но это неприятно, и я уверен, что есть лучший способ.

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

 const manifest = { start_url: 'appshell' };
  

Затем я использую self.location , чтобы получить путь к service worker. Это включает в себя имя файла, поэтому я обрезаю его в конце:

 // if file is 'sw.js' that's 5 chars off the end
const applicationRoot = new URL(self.location.href.slice(0, -5)   manifest.start_url); 
  

Тогда я могу проверить это:

 self.addEventListener('fetch', (event: FetchEvent) => {
    // This MUST be synchronous until respondWith is called

    const url = new URL(event.request.url);
    if (url.pathname === applicationRoot.pathname) {
        // Request is for the start_url, always return something so the PWA starts offline
        event.respondWith(...):
    }

    // ... see question for rest
});
  

Это неуклюже, но, по крайней мере, он всегда может обслуживать кэш start_url , не кэшируя все остальное, так что на данный момент это принятый ответ. Мне бы хотелось увидеть лучший способ сделать это, в идеале без жесткого кодирования / выборки manifest.json , чтобы изменения конфигурации там не требовали нового service worker.