首页 > 解决方案 > 在 chrome 上使用 service worker 时,从内存缓存中提供脚本文件

问题描述

我已经使用服务工作者完成了 PWA,我只是在 html 文件中导入脚本文件,如下所示

如果我更新 HTML 或脚本文件中的更改,则该更新不会反映在服务工作者中,总是 chrome 从内存缓存中提供文件......但 firfox 提供来自服务工作者的更新文件。

我想知道,为什么会发生这种情况......解决这个问题的任何解决方案

下面一个是html文件

<html>

    <body>

        
        <div><h1>Staic,Hello All! </h1></div>

        <script src="2.js"></script>

    </body>

</html>

下面是脚本文件(2.js)

const text = '<h1>Dynamic Hello All!</h1>'
const div = document.createElement('div')
div.innerHTML = text
document.body.appendChild(div)

if ('serviceWorker' in navigator) {
    window.addEventListener('load', function() {
      navigator.serviceWorker.register('/sw2.js').then(function(registration) {
        
        console.log('ServiceWorker registration successful with scope: ', registration.scope);
      }, function(err) {
     
        console.log('ServiceWorker registration failed: ', err);
      });
    });
}


下面是服务工作者文件

var cacheName = 'b7';
// var cacheAssets = [
//     '/1.html',
//     '/1.js',
  
// ]


self.addEventListener('install', e => {

    // e.waitUntil(
    //     caches.open(cacheName)
    //     .then(cache => {
    //         console.log(`Service Worker: Caching Files: ${cache}`);
    //         cache.addAll(cacheAssets)
    //             .then(() => self.skipWaiting())
    //     })
    // );
})

self.addEventListener('activate', e => {
    console.log('Service Worker: Activated');
    e.waitUntil(
        caches.keys().then(cacheNames => {
            return Promise.all(
                cacheNames.map(
                    cache => {
                        if (cache !== cacheName) {
                            console.log('Service Worker: Clearing Old Cache');
                            return caches.delete(cache);
                        }
                    }
                )
            )
        })
    );
})

// self.addEventListener('fetch', e => {
//     console.log('Service Worker: Fetching');
//     e.respondWith(
//         fetch(e.request).catch(() => caches.match(e.request))
        
//     );
// });

self.addEventListener('fetch', e => {
    console.log('Service Worker: Fetching');
    e.respondWith(
        fetch(e.request)
        .then(res => {
         
            const resClone = res.clone();
           
            caches.open(cacheName)
                .then(cache => {
                  
                    cache.put(e.request, resClone);
                });
            return res;
        }).catch(
            err => caches.match(e.request)
            .then(res => res)
        )
    );
});

标签: google-chromefirefoxservice-worker

解决方案


fetch这是 Chrome 中的预期行为,但它绝对依赖于浏览器并且有点令人惊讶,因为它违反了一旦服务工作者控制客户端,每个请求都会触发事件的假设。

这个较老的问题有更多上下文:Chrome service worker not intercepting cached requests

我的建议是在您的响应中明确设置Cache-Control:标头,以确保在可以从 HTTP 缓存中使用响应之前始终需要重新验证步骤。如果明确需要重新验证,则不会使用内存缓存,并且重新验证请求将fetch在您的 service worker 中触发一个事件。


推荐阅读