Как уменьшить размер кэша работника сервиса при кешировании запросов с помощью токенов CSRF - PullRequest
0 голосов
/ 06 мая 2018

У меня есть сервисный работник, который кэширует запросы из браузера, поэтому страница работает в автономном режиме. Однако каждый раз, когда пользователь выходит из системы и обратно, генерируется новый токен CSRF, и все предыдущие кэшированные данные бесполезны, поскольку запросы содержат маркер CSRF как часть строки запроса. Это требует повторного кэширования всех одних и тех же данных снова, поэтому у нас остается несколько копий данных в кеше, каждая из которых просто имеет свой URL-адрес запроса из-за разных токенов CSRF.

Сначала запрашиваю сеть, затем переключаюсь в кеш, если сеть недоступна.

Как мне обращаться с кэшированием этих ответов относительно токена CSRF? Должен ли я вручную удалить токен CSRF из значения event.request перед выполнением функций cache.put () и cache.match ()? Это даже разрешено? Изменяя URL-адрес запроса, кажется, что ранее кэшированное значение для этого запроса все еще может быть возвращено, даже если пользователь вышел из системы и снова вошел в систему, что было бы желаемым поведением.

Кроме того, как я могу удалить все кэшированные запросы, которые не соответствуют текущему токену CSRF, без очистки всех записей из кэша?

Вот соответствующий код сервисного работника:

self.addEventListener('fetch', function(event) 
// 'fetch' event lister: if the network is UP, fetch the data across the network and cache the result.
// If network is unavailable, attempt to fetch from cache.
{
    // Send a response, first by trying the network, then by looking in cache.  If both fail, an error occurs.
    event.respondWith(
        // Try to fetch the request from the network:       
        fetch(event.request)
            // If successful, cache a clone of the response, then return it.
            .then(function(response)
            {
                var r = response.clone();

                caches.open('offline-cache')
                    .then(function(cache)
                    {
                        cache.put(event.request, r);
                    })
                    .catch(function(error)
                    {
                        console.log("Unable to cache item: ", error);
                    });

                return response;
            })
            // If network fails, try to pull the item from cache.
            .catch(function(error)
            {
                // Open the cache
                return caches.open('offline-cache')
                    // When cache is open, attempt to match with desired request
                    .then(function(cache)
                    {
                        // Try to match:
                        return cache.match(event.request)
                        // If successful, return the match.  Errors bubble up to the main event.
                            .then(function(response)
                            {
                                return response;
                            });
                    })
                    .catch(function(error)
                    {
                        console.log("Cached entry not found. Error.");
                    });
            })
    ); // END event.respondWith
});

1 Ответ

0 голосов
/ 06 мая 2018

Если ресурсы для кэширования идентичны для всех запросов / пользователей и могут быть идентифицированы путем удаления определенных параметров URL (или полного удаления строки запроса), ваш код может создать URL-адрес ключа кэша и использовать эту строку вместо Request объекты для методов API Fetch и Cache:

// Returns URL string used for caching that excludes authentication-specific URL params, etc
function getCacheKeyUrl(request) {
  // Strip query string from URL
  return request.url.replace(/\?.*/,'');
}

self.addEventListener('fetch', event => {
  const cacheKeyUrl = getCacheKeyUrl(event.request);

  ...
});

Тогда вы можете использовать fetch(cacheKeyUrl), cache.put(cacheKeyUrl, r), cache.match(cacheKeyUrl) и т. Д. В вашем коде.

...