Uncaught DOMException (в обещании) - Hijack-специфичный запрос GraphQL в сервисной программе - PullRequest
0 голосов
/ 15 января 2019

Я пытаюсь перехватить определенный GraphQL-запрос через сервисного работника, чтобы подделать ответ от данных в моей IndexedDB, но я получаю ошибку, на которую событие уже было получено ответом. Выборка работает для кэшированных файлов, если извлеченные данные не находятся в кэше, он будет использовать сеть. Если нет сети, будет автономный запасной вариант. Как я могу организовать свои Обещания, чтобы я также мог перехватывать запросы к моему API GraphQL и определенному запросу (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 __ и мое имя_операции

sw.js:41 Uncaught (in promise) DOMException: Failed to execute 'respondWith' on 'FetchEvent': The event has already been responded to.

1 Ответ

0 голосов
/ 15 января 2019

Это редко документировано, но вам нужно немедленно вызвать метод в обработчике. Если обработчик события завершается и respondWith не был вызван, запрос будет обработан , чтобы был получен ответ по умолчанию. respondWith проверит dispatch flag, установленный только во время вызова обработчика события - когда вы вызываете его только из обратного вызова, вы получите « Событие уже получено"исключение.

Так что вам нужно изменить код, чтобы передать все обещание на respondWith:

if (event.request.url === __GRAPHQL_URL__) {
    event.respondWith(event.request.clone().json().then(({operationName, variables}) => {
//  ^^^^^^^^^^^^^^^^^^
        switch (operationName) {
            case 'getOfflineFacilities':
                return serveOfflineFacilities();
//              ^^^^^^
        }
    }));
//    ^
}
...