【问题标题】:Intercept fetch for the first time but not afterwards using serviceWorker第一次拦截获取,但之后不使用 serviceWorker
【发布时间】:2022-09-10 21:51:00
【问题描述】:

在这里需要服务人员的一些指导。

安装服务工作者时,它会缓存资产。在下一次重新加载时,当任何请求被发出时,它会被 service worker 拦截,它首先检查缓存,如果没有找到,然后我们进行网络调用。但是第二次网络调用再次被服务工作者拦截,因此它变成了一个无限循环。

我不希望下一个 fetch 调用再次被拦截。我希望我能够在这里解释这个问题。

这是 serviceWorker.js

const cacheVersion = \"v11\";
self.addEventListener(\'install\',(event)=>{
    self.skipWaiting();
    event.waitUntil(caches.open(cacheVersion).then((cache)=>{
        cache.addAll([
            \'/\',
            \'/index.html\',
            \'/style.css\',
            \'/images/github.png\',
        ])
        .then(()=>console.log(\'cached\'),(err)=>console.log(err));
    }))
})

self.addEventListener(\'activate\',event=>{
    event.waitUntil(
        (async ()=>{
            const keys = await caches.keys();
            return keys.map(async (cache)=>{
                if(cache !== cacheVersion){
                    console.log(\"service worker: Removing old cache: \"+cache);
                    return await caches.delete(cache);
                }
            })
        })()
    )
})

const cacheFirst = async (request) => {
    try{
        const responseFromCache = await caches.match(request);
        if (responseFromCache) {
        return responseFromCache;
        }
    }
    catch(err){
        return fetch(request);
    }
    return fetch(request);
};

self.addEventListener(\"fetch\", (event) => {
    event.respondWith(cacheFirst(event.request));
});

    标签: javascript service-worker


    【解决方案1】:

    这里的原因是你的cacheFirst,有点不对劲。我们想在其中做什么(高级算法)?应该是这样的吧?

    • 检查缓存,如果找到匹配 - 返回
    • 否则,从服务器获取、缓存并返回
    • 否则,如果网络失败 - 返回一些“虚拟”响应
    const cacheFirst = async (request) => {
      
      // First try to get the resource from the cache
      const responseFromCache = await caches.match(request);
      if (responseFromCache) {
        return responseFromCache;
      }
    
      // Next try to get the resource from the network
      try {
        const responseFromNetwork = await fetch(request);
        // response may be used only once
        // we need to save clone to put one copy in cache
        // and serve second one
        putInCache(request, responseFromNetwork.clone());
        return responseFromNetwork;
      } catch (error) {
        // well network failed, but we need to return something right ?
        return new Response('Network error happened', {
          status: 408,
          headers: { 'Content-Type': 'text/plain' },
        });
      }
    };
    

    这不是现成的解决方案!!!将其视为伪代码,例如您可能需要先实现 putInCache

    【讨论】:

    • 太感谢了。这就是我一直在寻找的逻辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多