首先,您需要了解 Service Worker 层与前端和服务器是分离的。它位于中间并拦截所有网络请求,以便您决定如何处理它们。
服务工作者获取事件处理程序有一个参数,事件。
您可以“解析”此对象以获取有关请求、event.request 的信息并决定应如何处理。
例如,您很可能不想缓存 POST、PUT 或 DELETE 请求,因此只需通过调用 fetch 将这些请求传递到网络。仅测试 GET 请求,以简化此操作。
self.addEventListener("fetch", event => {
event.respondWith(
if(event.request.mode === "GET") {
//compare URL against rules table
//perform caching strategy for this URL
} else {
return fetch(event);
}
);
});
如果您可能有要应用到 URL 的缓存策略,那么您需要查看可能要应用的策略。 FWIW,我可能会采用大约 25 种不同的策略,所以我会尽量简化。
这是我将 URL 与缓存策略匹配的方法示例:
function testRequestRule( request, rules ) {
for ( let i = 0; i < rules.length; i++ ) {
if ( rules[ i ].route && rules[ i ].route.test( request.url ) ) {
return rules[ i ];
} else if ( rules[ i ].destination &&
rules[ i ].destination === request.destination ) {
return rules[ i ];
}
}
}
这是一个规则对象的样子:
let routeRules = [ {
"route": /img\/products\//,
"strategy": "cacheFallingBackToNetworkCache",
"options": {
cacheName: prodPhotos,
fallback: offlineProductPhoto
}
},....]
然后我将对请求执行所需的策略:
if ( rule.strategy ) {
switch ( rule.strategy ) {
case "cacheFallingBackToNetwork":
return responseManager.cacheFallingBackToNetworkCache(
event.request, rule.cacheName || cacheName,
rule.options.fallback );
case "fetchAndRenderResponseCache":
return responseManager.fetchAndRenderResponseCache( {
request: event.request,
pageURL: rule.options.pageURL,
template: rule.options.template,
api: rule.options.api,
cacheName: rule.cacheName || cacheName
} )
.then( response => {
invalidationManager.cacheCleanUp( rule.cacheName || cacheName );
return response;
} );
case "cacheOnly":
return responseManager.cacheOnly( event.request, rule.cacheName || cacheName )
.then( response => {
invalidationManager.cacheCleanUp( rule.cacheName || cacheName );
return response;
} );
case "networkOnly":
return responseManager.networkOnly( event.request );
case "custom":
return rule.options.handler( event, rule );
default:
return responseManager
.cacheFallingBackToNetworkCache( event.request,
rule.cacheName || cacheName,
rule.options.fallback )
.then( response => {
invalidationManager.cacheCleanUp( rule.cacheName || cacheName );
if ( response ) {
return response;
} else {
return simpleFetch( event );
}
} )
.catch( error => {
console.error( "fetch error: ", error );
console.error( "url: ", event.request.url );
} );
}
} else {
return simpleFetch( event );
}
简而言之,您可以控制每个网络请求的处理方式,这就是 service worker 的美妙之处。你只需要创建逻辑来处理这个问题,并且没有什么灵丹妙药可以让你成为一名优秀的服务人员。您必须自己编写代码,当然还要对其进行测试。 :)