Работник сервиса: Кэшировать только по имени файла, а не по URL - PullRequest
0 голосов
/ 20 ноября 2018

Я заметил, что когда вы кешируете файл с работником службы

event.respondWith(
    caches.match(event.request)
        .then(function(response) {
            if (response) {
                return response;
            }
            return fetch(event.request);
        }
    )
);

enter image description here

файл кэшируется на основе URL

/bundle/v1/assets/icon.svg 

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

/bundle/v1/assets/icon.svg 
/bundle/v2/assets/icon.svg 
/bundle/v3/assets/icon.svg 

Возможно ли что-то подобное?

1 Ответ

0 голосов
/ 20 ноября 2018

Что вы можете сделать, так это немного проявить изобретательность, когда читаете и пишете в Cache Storage API, нормализуя URL-адреса перед использованием их в качестве ключей.

Чтобы использовать ваш пример, скажем, вы знаете, чтокаждый раз, когда вы взаимодействуете с Cache Storage API (чтение или запись) для URL-адреса, заканчивающегося icon.svg, вы всегда ожидаете, что он ссылается на один и тот же базовый Response, независимо от полного URL-адреса.Вы можете сделать что-то вроде следующего:

// A "fake" prefix used for all the normalized entries.
// Choose something that is not used by your real URLs.
const NORMALIZED_PREFIX = '/__normalized/';

// A list of "files" whose URLs you want to normalize.
const FILES_TO_NORMALIZE = [
  'icon.svg',
  // ...anything else...
];

function normalizeUrl(request) {
  // Convert the request.url string into a URL object,
  // so that we can get the pathname cleanly.
  const url = new URL(request.url);

  for (const file of FILES_TO_NORMALIZE) {
    if (pathname.endsWith(file)) {
      // If we have a match, then normalize the URL by using our
      // standard prefix along with the specific file name.
      url.pathname = NORMALIZED_PREFIX + file;
      return url.href;
    }

  }

  // Otherwise, just return the original request's URL.
  return request.url;
}

self.addEventListener('fetch', event => {
  // This is a naive cache-first strategy. Customize to suit your needs:
  // https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/
  event.respondWith(async function() {
    const requestKey = normalizeRequestUrl(event.request);

    const cache = await caches.open('runtime-cache');
    const cachedResponse = await caches.match(requestKey);

    // If there's a cached response, use it.
    if (cachedResponse) {
      return cachedResponse;
    }

    // Otherwise, get a response from the network for the original request.
    // Make sure you *don't* call fetch(requestKey),
    // since that URL doesn't exist on the server!
    const networkResponse = await fetch(event.request);

    // When you save the entry in the cache, use cache.put()
    // with requestKey as the first parameter.
    await cache.put(requestKey, networkResponse.clone());

    return networkResponse;
  }());
});
...