我已经实现了一个服务工作者,它可以缓存所有脱机使用的请求,这很好。但是每次加载页面时,都会有两个请求命中我的Web服务器(一个来自服务工作者,另一个来自浏览器)!
如何缓存请求并仅将页面加载一次?
service-worker.js
self.addEventListener('install', function(event) {
//load error page which will show if user has no internet
var errorPage = new Request('/?p=error&offline');
event.waitUntil(pushToCache(errorPage));
});
//If any fetch fails, it will look for the request in the cache and serve it from there first
self.addEventListener('fetch', function(event) {
event.waitUntil(pushToCache(event.request));
event.respondWith(
fetch(event.request) //try loading from internet
.catch(function (error) {
return fetchFromCache(event.request);
}) //no internet connection try getting it from cache
);
});
function pushToCache(request){
if(request.method == "GET"){
return caches.open('stm-app').then(function (cache) {
return fetch(request).then(function (response) {
return cache.put(request, response);
});
});
}
};
function fetchFromCache(request) {
return caches.open('stm-app').then(function (cache) {
return cache.match(request).then(function (matching) {
if(!matching || matching.status == 404){
return fetchFromCache(new Request('/?p=error&offline')); //show page that user is offline
}else{
return matching;
}
});
});
}
sw-register.js
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js')
.then(function(registration) {
console.log('Registered:', registration);
})
.catch(function(error) {
console.log('Registration failed: ', error);
});
}
答案 0 :(得分:2)
因此,只要您提出请求,就会发生以下情况:
pushToCache()
将获取请求发送到服务器以缓存响应,是的,这很有意义,对于最初发出的每个请求,它只向服务器发送了两个请求,两个服务器。
您可能要考虑的一件事是首先从缓存中响应,然后在网络上获取最新数据。这样,您就可以避免由于连接问题而导致的加载延迟,即使在用户在线时,也可以加快页面的加载时间。
让我们考虑以下情形:用户或服务器都处于脱机状态。触发请求后,它必须超时才能进入promise的catch部分并获取缓存的响应。
拦截事件后,您可以做的就是检查缓存是否匹配,如果发现任何内容,请对该事件做出响应。然后启动获取请求以更新缓存。 现在,如果找不到任何内容,请触发获取请求,克隆响应(因为响应正文只能使用一次),以原始响应进行响应,然后使用克隆的响应更新缓存。
我们做到了什么?
无论用户是在线,离线还是在Lie-Fi上,用户都可以立即得到响应!
服务器最多收到一个请求,并且缓存将始终使用服务器中的最新数据进行更新!
serviceworke.rs是一个很好的资源,可以帮助您了解如何使用Service Workers做很多有趣的事情。
This page特别详细地解释了我上面所说的内容。