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 控制台中看到关于如何无法响应已处理的事件的错误.
我们有从我们的媒体服务器重定向到 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 控制台中看到关于如何无法响应已处理的事件的错误.