未捕获的DOMException(承诺)-在服务工作人员中劫持特定的GraphQL请求

时间:2019-01-15 14:56:26

标签: javascript es6-promise service-worker fetch-api

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

1 个答案:

答案 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();
//              ^^^^^^
        }
    }));
//    ^
}