我试图通过服务工作者劫持特定的GraphQL-Request以伪造IndexedDB中数据的响应,但是我收到一个错误,表明该事件已得到响应。提取对缓存的文件有效,如果提取的数据不在缓存中,它将使用网络。如果没有网络,将存在脱机后备。我如何协调我的承诺,即我也可以劫持对GraphQL API和特定查询(operationName)的请求,因为似乎我搞砸了async event.respondWith调用?
self.addEventListener('fetch', function (event) {
if (event.request.url === __GRAPHQL_URL__) {
event.request.clone().json().then(({operationName, variables}) => {
switch (operationName) {
case 'getOfflineFacilities':
//when a fetch is matching there will be the error
event.respondWith(serveOfflineFacilities());
}
});
}else{
event.respondWith(
caches.match(event.request).then(function (response) {
console.log("cache or network fallback");
return response || fetch(event.request);
}).catch(function () {
console.log("offline fallback");
return caches.match('/index.html');
})
);
}
});
当GraphQL查询命中 __ GRAPHQL_URL __ 和我的 operationName
时出错 sw.js:41 Uncaught (in promise) DOMException: Failed to execute 'respondWith' on 'FetchEvent': The event has already been responded to.
答案 0 :(得分:1)
文档稀疏,但是您需要在处理程序中立即调用respondWith
method 。如果事件处理程序退出并且尚未调用respondWith
,则请求will be handled将会提供默认响应。 respondWith
will check the dispatch flag
仅在事件处理程序调用期间设置-当您仅从promise回调中调用它时,您将获得“ 事件已响应”异常。
因此,您需要更改代码以将整个承诺传递给respondWith
:
if (event.request.url === __GRAPHQL_URL__) {
event.respondWith(event.request.clone().json().then(({operationName, variables}) => {
// ^^^^^^^^^^^^^^^^^^
switch (operationName) {
case 'getOfflineFacilities':
return serveOfflineFacilities();
// ^^^^^^
}
}));
// ^
}