服务人员使js运行两次



我从pwabuilder.com实现了服务工作者,它运行得很好

问题是,即使浏览器在线,服务工作者也会运行,所以每个js函数都会运行两次,一次来自服务工作者,另一次来自我的其他js文件

在运行js函数之前,我应该看看它是否是一个活动的服务工作者,还是应该以某种方式确保浏览器联机时服务工作者没有运行?

这是我在主索引文件中运行的代码

if (navigator.serviceWorker.controller) {
//console.log('[PWA Builder] active service worker found, no need to register')
} else {
//Register the ServiceWorker
navigator.serviceWorker.register('pwabuilder-sw.js', {
scope: './'
}).then(function (reg) {
//console.log('Service worker has been registered for scope:' + reg.scope);
});
}

pwabuilder-sw.js如下所示:

self.addEventListener('install', function (event) {
var indexPage = new Request('');
event.waitUntil(
fetch(indexPage).then(function (response) {
return caches.open('pwabuilder-offline').then(function (cache) {
//console.log('[PWA Builder] Cached index page during Install' + response.url);
return cache.put(indexPage, response);
});
}));
});
//If any fetch fails, it will look for the request in the cache and serve it from there first
self.addEventListener('fetch', function (event) {
var updateCache = function (request) {
return caches.open('pwabuilder-offline').then(function (cache) {
return fetch(request).then(function (response) {
//console.log('[PWA Builder] add page to offline' + response.url);
return cache.put(request, response);
});
});
};
event.waitUntil(updateCache(event.request));
event.respondWith(
fetch(event.request).catch(function (error) {
//Check to see if you have it in the cache
//Return response
//If not in the cache, then return error page
return caches.open('pwabuilder-offline').then(function (cache) {
return cache.match(event.request).then(function (matching) {
var report = !matching || matching.status === 404 ? Promise.reject('no-match') : matching;
return report;
});
});
})
);
});

服务人员在注册、安装和激活后一直工作

服务工作者是事件驱动的,他们的主要用途是充当缓存代理处理网络请求存储内容以供离线使用。其次是处理推送消息

我相信您理解,为了充当缓存代理,无论应用程序是联机还是脱机,服务工作者都将运行。您需要考虑各种缓存场景。

很难为上述问题提供确切的解决方案:"每个js函数运行两次">
我怀疑所有JS函数是否总是运行两次。这似乎取决于实现。

服务工作者不能在其自己的路径之上具有作用域,默认情况下,它将控制服务工作者作用域之下的所有资源,此作用域也可以受到限制。

navigation.serviceWorker.register(
'/pwabuilder-sw.js', { //SW located at the root level here
scope: '/app/' //to control all resource accessed form within path /app/
}
);

我相信pwabuilder.com的脚本确实试图缓存所有资源,甚至是不应该缓存的资源,例如POST请求。您可能需要根据使用的资源类型修改缓存策略。

这里没有简单的解决方案,也无法提供简单的答案。

通常,您可以使用服务工作者以以下方式之一缓存资源:

  • 缓存回退到网络

    self.addEventListener('fetch', (event) => {
    event.responseWith(
    caches.match(event.request)
    .then((response) => {
    return response || fetch(event.request);
    })
    );
    });
    
  • 网络回退到缓存

    //Good for resources that update frequently
    //Bad for Intermittend and slow connections
    self.addEventListener('fetch', (event) => {
    event.responseWith(
    fetch(event.request).catch(() => {
    return caches.match(event.request);
    })
    );
    });
    
  • 缓存然后网络

    //Cache then network(1) (send request to cache and network simultaneousely)
    //show cached version first, then update the page when the network data arrives
    var networkDataReceived = false;
    var networkUpdate = fetch('/data.json')
    .then((response) => {
    return response.json();
    }).then((data) => {
    networkDataReceived = true;
    updatePage(data);
    });
    //Cache then network(2)
    caches.match('/data.json')
    .then ((response) => {
    return response.json();
    }).then((data) => {
    if (!networkDataReceived) {
    updatePage(data);
    }
    }).catch(() => {
    return networkUpdate;
    });
    
  • 通用后备

    self.addEventListener('fetch', (event) => {
    event.responseWith(
    caches.match(event.request)
    .then((response) => {
    return response || fetch(event.request);
    }).catch(() => {
    return caches.match('offline.html');
    })
    )
    });
    

我希望以上内容至少能帮助您找到您面临的确切问题
干杯!

React添加了这个React.strectMode HOC,它运行两次应用程序的某些部分,如类组件构造函数、render和shouldComponentUpdate方法
检查文档:
https://reactjs.org/docs/strict-mode.html#detecting-意想不到的副作用。

看看你的index.js文件顶部是否有<React.StrictMode>,如果有,你可能想在没有它的情况下运行测试。

最新更新