1

我们有从我们的媒体服务器重定向到 CDN 的图像,我试图从我的服务工作者逻辑中排除这些图像,以解决 Chrome 40 中的错误。在 Canary 中,同一个工作者能够正常工作。我认为有一个event.default()回退到标准行为,但我没有在 Chrome 的实现中看到这一点,并且阅读规范似乎目前的建议是只使用fetch(event.request).

所以我遇到的问题是我是否必须等到 99% 的所有用户迁移到 Chrome 41+ 才能在这种情况下使用服务人员,或者有什么方法可以让我选择退出某些请求?

我的逻辑核心如下:

worker.addEventListener('install', function(event){
    event.waitUntil(getDefaultCache().then(function(cache){
        return cache.addAll(precacheUrls);
    }));
});

worker.addEventListener('fetch', function(event){
    event.respondWith(getDefaultCache().then(function(cache){
        return cache.match(event.request).then(function(response){
            if (!response){
                return fetch(event.request.clone()).then(function(response){
                    if (cacheablePatterns.some(function(pattern){
                        return pattern.test(event.request.url);
                    })) {
                        cache.put(event.request, response.clone());
                    }

                    return response;
                });
            }

            return response;
        });
    }));
});
4

1 回答 1

4

一旦你在里面,event.respondWith()你确实需要发出响应,否则你会招致网络错误。您是对的,event.default()目前尚未实施。

一个通用的解决方案是event.respondWith()如果您可以同步确定您不想处理该事件,则不要输入。一个基本的例子是这样的:

function fetchHandler(event) {
  if (event.request.url.indexOf('abc') >= 0) {
    event.respondWith(abcResponseLogic);
  } else if (event.request.url.indexOf('def') >= 0) {
    event.respondWith(defResponseLogic);
  }
}
self.addEventListener('fetch', fetchHandler);

如果event.respondWith()未调用,则此fetch处理程序是无操作的,并且任何其他注册fetch的处理程序都会收到请求。多个fetch处理程序按照它们添加的顺序被调用addEventListener,一次一个,直到第一个调用event.respondWith()。如果没有获取处理程序调用event.respondWith(),那么用户代理会像没有服务工作者参与时一样正常发出请求。

需要考虑的一件棘手的事情是,event.respondWith()需要在每个fetch处理程序内部同步地确定是否调用。任何依赖异步承诺解析的东西都不能用来确定是否调用event.respondWith(). 如果您尝试执行异步操作然后调用event.respondWith(),您最终会遇到竞争条件,并且可能会在服务工作人员控制台中看到有关您如何无法响应已处理的事件的错误。

于 2015-02-09T02:13:22.383 回答