Chrome Service Worker 的 M40 重定向错误的任何解决方法?

Any workaround for Chrome M40 redirect bug for service workers?

我们有从我们的媒体服务器重定向到 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;
        });
    }));
});

进入 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(),则用户代理会像没有 service worker 参与时的正常情况一样发出请求。

需要考虑的一件棘手的事情是关于是否调用 event.respondWith() 的决定需要在每个 fetch 处理程序中同步完成。任何依赖于异步承诺解析的东西都不能用于确定是否调用 event.respondWith()。如果您尝试执行一些异步操作然后调用 event.respondWith(),您将以竞争条件告终,并且可能会在 Service Worker 控制台中看到关于如何无法响应已处理的事件的错误.