我的服务工作人员有一个变量来存储安全哈希,并将其注入到相关 HTTP 请求的标头中,然后服务器应用程序将与它自己的进行比较以使其成为安全登录。
哈希值是在后面动态生成的(在我的例子中使用 c# dotnet 在浏览器类中)。
以前我总是在从浏览器加载的页面上调用 postmessage 将哈希值更新到 sw 中。但遇到了一个问题,在 5-6 分钟不活动(未打开 devtools)的情况下,一旦单击页面上的按钮,sw 就会重新初始化或以空哈希值唤醒,从而以空值响应并验证失败。
所以我从 sw 添加了一个触发器,但随后遇到了消息侦听器和获取侦听器之间的竞争条件。我需要消息侦听器来更新 sw 中的哈希值,但同时获取侦听器重新定位。看来超时延迟不起作用。
console.log('top root log');
if (!self.secureHeader) {
self.secureHeader = 'Empty';
console.log('Refreshing header');
// this is my trigger when sw re-init
postMessage({ type: 'refreshHeader', msg: '' }, '*');
//// this is a bad attempt which didn't block the listener
// setTimeout(function() {
// console.log('timeout ended');
// }, 50);
}
self.addEventListener('message', function (event) {
if (event.data.type == 'setHeader') {
self.secureHeader = event.data.msg;
console.log('Header received:'+ self.secureHeader);
}
}, false);
self.addEventListener('fetch', function(e) {
console.log(Responding: ${self.secureHeader});
////I tried timeout here, error: The event handler is already finished.
//if (self.secureHeader === 'Empty')
//timeout to do respond
e.respondWith(
fetch(request, {
headers: getSecureHeaders(request)
})
.catch(() => {
return caches.match(request);
})
);
});
根据我的测试,经过几分钟的等待和 sw 到期,
日志似乎是:
(sw 唤醒)顶部根日志出现。
触发“刷新标题”。
获取事件开始。
然后“已收到标头”和“正在响应...”同时出现,
我怎样才能正确地链接它们?任何建议,谢谢。
创建超时不会停止获取事件处理程序。在提出
fetch()
请求之前,您需要一个可以等待的承诺。您可以在请求刷新的标头时初始化该承诺:
// runs when sw (re-)init
self.secureHeaderPromise = new Promise(resolve => {
console.log('Refreshing header');
postMessage({ type: 'refreshHeader', msg: '' }, '*');
self.setSecureHeader = (value) => {
console.log('First header received: '+value);
resolve(value);
// allow later updates
self.setSecureHeader = (value) => {
console.log('Header received :'+value);
self.secureHeaderPromise = Promise.resolve(value);
};
};
});
self.addEventListener('message', function (event) {
if (event.data.type == 'setHeader') {
self.setSecureHeader(event.data.msg);
}
}, false);
self.addEventListener('fetch', function(e) {
console.log(`Got request: ${e}`);
e.respondWith(
self.secureHeaderPromise.then(secureHeader => {
console.log(`Responding: ${secureHeader}`);
return fetch(request, {
headers: getSecureHeaders(request)
})
}).catch(() => {
return caches.match(request);
})
);
});