仅在 Chrome(Service Worker)中:'...重定向响应用于重定向模式不是 "follow" 的请求'
Only in Chrome (Service Worker): '... a redirected response was used for a request whose redirect mode is not "follow" '
当我在 Chrome 中刷新(或离线)时,我得到 "This site can't be reached" 并且以下内容记录到控制台:The FetchEvent for "http://localhost:8111/survey/174/deployment/193/answer/offline/attendee/240/" resulted in a network error response: a redirected response was used for a request whose redirect mode is not "follow".
。当我在 Firefox 中刷新时,一切正常。有人可以解释为什么会这样吗?
这是我简化的软件。
importScripts("/static/js/libs/idb.js")
var CACHE_NAME = "upshot-cache-version3"
var urlsToCache = [...]
self.addEventListener("install", event => {
event.waitUntil(
caches
.open(CACHE_NAME)
.then(cache => {
urlsToCache.map(url => cache.add(url))
})
)
})
self.addEventListener("activate", event => {
clients.claim()
})
self.addEventListener('fetch', event => {
event.respondWith(
caches
.match(event.request)
.then(response => {
if (response) {
return response
}
var fetchRequest = event.request.clone()
return fetch(fetchRequest).then(response => {
if (!response || response.status !== 200 || response.type !== 'basic') {
return response
}
var responseToCache = response.clone()
caches.open(CACHE_NAME).then(cache => cache.put(event.request, responseToCache))
return response
})
})
)
})
这是由于(相对)最近更改了关于可以使用哪种响应来满足导航的安全限制。它应该适用于所有支持服务工作者的浏览器(即今天的 Chrome 和 Firefox),但您可能正在使用过时的 Firefox 版本进行测试。
可以在这个issue tracker entry, and there's also more background关于导致基础规范的决定中找到更改内容的背景。
在修改您的服务工作者以处理安全限制方面,如果您当前正在响应某些 URL 的导航请求,并使用 HTTP 30x 重定向到另一个 URL,您'需要注意不要将重定向的响应直接存储在缓存中。
您可以通过检查 response.redirected
是否为 true
来判断给定的响应是否被重定向,如果是,则使用类似于此的代码(改编自 Workbox 项目) 创建一个 "clean" 响应副本,然后可以将其存储在缓存中:
function cleanResponse(response) {
const clonedResponse = response.clone();
// Not all browsers support the Response.body stream, so fall back to reading
// the entire body into memory as a blob.
const bodyPromise = 'body' in clonedResponse ?
Promise.resolve(clonedResponse.body) :
clonedResponse.blob();
return bodyPromise.then((body) => {
// new Response() is happy when passed either a stream or a Blob.
return new Response(body, {
headers: clonedResponse.headers,
status: clonedResponse.status,
statusText: clonedResponse.statusText,
});
});
}
当我在 Chrome 中刷新(或离线)时,我得到 "This site can't be reached" 并且以下内容记录到控制台:The FetchEvent for "http://localhost:8111/survey/174/deployment/193/answer/offline/attendee/240/" resulted in a network error response: a redirected response was used for a request whose redirect mode is not "follow".
。当我在 Firefox 中刷新时,一切正常。有人可以解释为什么会这样吗?
这是我简化的软件。
importScripts("/static/js/libs/idb.js")
var CACHE_NAME = "upshot-cache-version3"
var urlsToCache = [...]
self.addEventListener("install", event => {
event.waitUntil(
caches
.open(CACHE_NAME)
.then(cache => {
urlsToCache.map(url => cache.add(url))
})
)
})
self.addEventListener("activate", event => {
clients.claim()
})
self.addEventListener('fetch', event => {
event.respondWith(
caches
.match(event.request)
.then(response => {
if (response) {
return response
}
var fetchRequest = event.request.clone()
return fetch(fetchRequest).then(response => {
if (!response || response.status !== 200 || response.type !== 'basic') {
return response
}
var responseToCache = response.clone()
caches.open(CACHE_NAME).then(cache => cache.put(event.request, responseToCache))
return response
})
})
)
})
这是由于(相对)最近更改了关于可以使用哪种响应来满足导航的安全限制。它应该适用于所有支持服务工作者的浏览器(即今天的 Chrome 和 Firefox),但您可能正在使用过时的 Firefox 版本进行测试。
可以在这个issue tracker entry, and there's also more background关于导致基础规范的决定中找到更改内容的背景。
在修改您的服务工作者以处理安全限制方面,如果您当前正在响应某些 URL 的导航请求,并使用 HTTP 30x 重定向到另一个 URL,您'需要注意不要将重定向的响应直接存储在缓存中。
您可以通过检查 response.redirected
是否为 true
来判断给定的响应是否被重定向,如果是,则使用类似于此的代码(改编自 Workbox 项目) 创建一个 "clean" 响应副本,然后可以将其存储在缓存中:
function cleanResponse(response) {
const clonedResponse = response.clone();
// Not all browsers support the Response.body stream, so fall back to reading
// the entire body into memory as a blob.
const bodyPromise = 'body' in clonedResponse ?
Promise.resolve(clonedResponse.body) :
clonedResponse.blob();
return bodyPromise.then((body) => {
// new Response() is happy when passed either a stream or a Blob.
return new Response(body, {
headers: clonedResponse.headers,
status: clonedResponse.status,
statusText: clonedResponse.statusText,
});
});
}