我试图通过服务工作者劫持特定的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.

最佳答案

它的文档很少,但是您需要在处理程序中立即调用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();
//              ^^^^^^
        }
    }));
//    ^
}

关于javascript - 未捕获的DOMException( promise )-在serviceworker中劫持特定的GraphQL请求,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54201388/

10-09 22:19