Service Worker的fetch事件永远不会触发

时间:2016-12-08 19:56:51

标签: javascript service-worker

问题标题说明了一切。

if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/react-redux/sw.js').then(() => {
        console.log('registered');
    }, err => console.log(err));
}

修改

看起来问题的根源是路径

navigator.serviceWorker.register('/react-redux/sw.js')

如果我移动sw代码,那么我有

navigator.serviceWorker.register('swRoot.js').then(() => {

然后一切正常。我尝试了上面我能想到的所有内容,从删除/ react-redux中的前导斜杠到添加{scope: './''/''/react-redux'和没有工作(有些导致错误)。

是否有人知道需要什么配置魔法才能从域的根目录以外的地方加载服务工作者?

然后是我的整个sw.js

self.addEventListener('install', function(event) {
    console.log('hello');
    try {
        console.log('typeof System in install', typeof System);
    } catch(e){}

    console.log('caching');
    event.waitUntil(
        caches.open('v1').then(function(cache) {
            console.log('caching - getting');
            return cache.addAll([
                '/react-redux/a.js'
            ]);
        }).catch(function(error){ console.log('error', error) })
    );
});

console.log('ADDING FETCH')
self.addEventListener('fetch', function(event) {
    console.log('fetching ->', event.request);
    event.respondWith(
        caches.match(event.request)
                .then(function(response) {
                    // Cache hit - return response
                    if (response) {
                        return response;
                    }
                    return fetch(event.request);
                })
    );
});

我从未收到console.log('fetching ->', event.request);消息。我甚至添加了这种愚蠢来试图强迫这个问题。

setTimeout(() => fetch('/react-redux/foo.css').then(r => console.log(r)), 1000);
setInterval(() => fetch('/react-redux/foo.css').then(r => console.log(r)), 5000);

我看到fetch事件正在运行,但服务工作者从不说它正在击中那些事件处理程序。

此外,我通知SW已注册,当我更新sw.js,关闭并重新打开时,我看到所有日志记录语句表明事情正在正确安装。

3 个答案:

答案 0 :(得分:3)

fetch事件处理程序

中附加install事件侦听器
self.addEventListener('install', function(event) {
  console.log("install");
  try {
    console.log('typeof System in install', typeof System);
  } catch (e) {}

  console.log('caching');
  event.waitUntil(
    caches.open('v1').then(function(cache) {
      console.log('caching - getting');
      return cache.addAll([
        'a.js'
      ]);
    }).catch(function(error) {
      console.log('error', error)
    })
  );

  self.addEventListener('fetch', function(event) {
    console.log('fetching ->', event.request);
    event.respondWith(
      caches.match(event.request)
      .then(function(response) {
        // Cache hit - return response
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
    );
  });
});

plnkr https://plnkr.co/edit/WuJCZSD0V4idG1Ra7VMb?p=preview

答案 1 :(得分:3)

获取拦截工作似乎需要注册 服务工作者使用HTML文件在树的级别或更高级别 注册工人。以下失败。

在Chrome中,请务必查看“应用程序”下的“服务工作者”。 即使在下面注册也会导致激活的服务工作者 并且正在运行,但当位置在HTML页面或其上方时,您 还会在“客户”下列出一个条目。似乎存在这种情况 完全对应于截取提取的时间。

答案 2 :(得分:3)

你正走在正确的轨道上,这似乎是一个范围问题。

要更改服务工作者的范围,必须在注册时完成,如下所示:

navigator.serviceWorker.register('scripts/sw.js', { scope: '/' })

然后服务器必须在响应中返回以下标头以确认此范围更改。

Service-Worker-Allowed: /

See this answer