Эффективный способ проверить, доступно ли кеш-хранилище в сервисном работнике - PullRequest
0 голосов
/ 29 января 2020

Мы можем проверить доступное хранилище перед кэшированием, используя приведенный ниже код здесь

if ('storage' in navigator && 'estimate' in navigator.storage) {
  navigator.storage.estimate().then(({usage, quota}) => {
    console.log(`Using ${usage} out of ${quota} bytes.`);
  });
}

Каков наилучший способ реализации этого кода для предотвращения ошибки Uncaught (in promise) DOMException: Quota exceeded в сервисном работнике при просмотре веб-сайт в режиме инкогнито в Google chrome и как он должен быть реализован?

Пожалуйста, дайте мне знать, если существует другая лучшая техника.

Вот рабочий код моего прогрессивного веб-приложения

var version = 'v2:';
var offlineFundamentals = [
    '/',
    '/offline.html'
];
var updateStaticCache = function () {
    return caches.open(version + 'fundamentals').then(function (cache) {
        return Promise.all(offlineFundamentals.map(function (value) {
            var request = new Request(value);
            var url = new URL(request.url);
            if (url.origin != location.origin) {
                request = new Request(value, {
                    mode: 'no-cors'
                });
            }
            return fetch(request).then(function (response) {
                var cachedCopy = response.clone();
                return cache.put(request, cachedCopy);
            });
        }))
    })
};
var clearOldCaches = function () {
    return caches.keys().then(function (keys) {
        return Promise.all(keys.filter(function (key) {
            return key.indexOf(version) != 0;
        }).map(function (key) {
            return caches.delete(key);
        }));
    });
};
var limitCache = function (cache, maxItems) {
    cache.keys().then(function (items) {
        if (items.length > maxItems) {
            cache.delete(items[0]);
        }
    })
};
var trimCache = function (cacheName, maxItems) {
    caches.open(cacheName).then(function (cache) {
        cache.keys().then(function (keys) {
            if (keys.length > maxItems) {
                cache.delete(keys[0]).then(trimCache(cacheName, maxItems));
            }
        });
    });
};
var hasUrlCacheExcludeMatch = function (url) {
    var cacheExcludeUrls = [
        "https:\/\/example.com\/user\/login",
        "https:\/\/example.com\/user\/register"
    ];
    return cacheExcludeUrls.some(path => url.includes(path));
};
self.addEventListener("install", function (event) {
    event.waitUntil(updateStaticCache().then(function () {
        return self.skipWaiting();
    }));
});
self.addEventListener("message", function (event) {
    var data = event.data;
    if (data.command == "trimCache") {
        trimCache(version + "pages", 80);
        trimCache(version + "images", 50);
        trimCache(version + "assets", 50);
    }
});
self.addEventListener("fetch", function (event) {
    var fetchFromNetwork = function (response) {
        var cacheCopy = response.clone();
        if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
            if (!hasUrlCacheExcludeMatch(event.request.url)) {
                caches.open(version + 'pages').then(function (cache) {
                    cache.put(event.request, cacheCopy).then(function () {
                        limitCache(cache, 80);
                    })
                });
            }
        } else if (event.request.headers.get('Accept').indexOf('image') != -1) {
            caches.open(version + 'images').then(function (cache) {
                cache.put(event.request, cacheCopy).then(function () {
                    limitCache(cache, 50);
                });
            });
        } else {
            caches.open(version + 'assets').then(function add(cache) {
                cache.put(event.request, cacheCopy).then(function () {
                    limitCache(cache, 50);
                });
            });
        }
        return response;
    }
    var fallback = function () {
        if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
            return caches.match(event.request).then(function (response) {
                return response || caches.match('/offline.html');
            })
        }
    }
    if (event.request.method != 'GET') {
        return;
    }
    if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
        event.respondWith(fetch(event.request).then(fetchFromNetwork, fallback));
        return;
    }
    event.respondWith(caches.match(event.request).then(function (cached) {
        return cached || fetch(event.request).then(fetchFromNetwork, fallback);
    }))
});
self.addEventListener("activate", function (event) {
    event.waitUntil(clearOldCaches().then(function () {
        return self.clients.claim();
    }));
});
...