我有一个基本的服务工作者,它返回一个离线页面时,没有互联网连接。在网站返回302重定向的任何地方,站点都会因为服务工作者的帐户而中断,而不管是在线还是离线。
服务工作者:
'use strict';
var cache_key = 'offline_cache_v18';
this.addEventListener('install', event => {
event.waitUntil(
caches.open(cache_key).then(function(cache) {
return cache.addAll([
'/offline.html'
]);
})
);
});
this.addEventListener('fetch', event => {
if (event.request.mode === 'navigate' || (event.request.method === 'GET' && event.request.headers.get('accept').includes('text/html')) ) {
event.respondWith(
fetch(event.request.url).catch(error => {
return caches.match('/offline.html');
})
);
} else {
event.respondWith(caches.match(event.request).then(function (response) {
return response || fetch(event.request);
}));
}
});中断服务工作进程的页面:
<?php header('Location: /'); ?>预期结果:页面照常加载,但离线时除外,此时应显示offline.html。
实际结果:站点无法完全加载响应为302重定向的页面,原因是“无法访问此站点”。控制台还报告说:“FetchEvent导致了网络错误响应:重定向响应用于重定向模式不是‘follow’的请求。”
已尝试:使用response.status检查响应代码,并尝试切换代码以使用'workbox‘库。我也尝试了{redirect:'follow'}参数,但对于这么简单的东西,它现在似乎变得相当高级。所有的“离线页面”教程似乎都有同样的bug。
发布于 2019-08-08 01:06:37
在中详细解释了基本的安全限制
这个问题会出现在导航请求中,因为这些请求使用'manual'的redirect mode。(大多数其他类型的请求将具有'follow'的redirect模式,这意味着可以使用重定向的HTTP30x响应来满足它们。)
您可以通过检查其redirected属性来检测是否有遵循HTTP30x重定向生成的Response对象。
综上所述:如何使用作为30x重定向的一部分生成的Response对象来满足导航请求的fetch事件?答案是首先“清理”重定向的响应,方法是创建一个新的(大部分相同的) Response对象,但该对象的redirected属性将设置为false。
async function cleanRedirect(response) {
const clonedResponse = response.clone();
return new Response(await clonedResponse.blob(), {
headers: clonedResponse.headers,
status: clonedResponse.status,
statusText: clonedResponse.statusText,
});
}您可以通过检查fetch处理程序内部的event.request.redirect === 'manual'来使用它。如果是,请在调用event.respondWith(response)之前检查response.redirected是否为true。如果是,则首先将重定向响应传递给await cleanRedirect()。
(此代码改编自Workbox的implementation。Workbox将为预先缓存的URL自动“清理”任何重定向的响应,但它不会对运行时缓存的URL执行自动清理。)
https://stackoverflow.com/questions/56903357
复制相似问题