Library Affected:
workbox-navigation-preload (4.3.1)
Browser & Platform:
Google Chrome 75.0.3770.142 on macOS 10.14.6
Error Description:
When using workbox.navigationPreload.enable(), it throws this error in the console.
The service worker navigation preload request was cancelled before 'preloadResponse' settled. If you intend to use 'preloadResponse', use waitUntil() or respondWith() to wait for the promise to settle.
service-worker.js:
workbox.navigationPreload.enable()
var route = new workbox.routing.NavigationRoute(new workbox.strategies.StaleWhileRevalidate({
cacheName: 'test',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 1
})
]
})
workbox.routing.registerRoute(route)
Am I doing anything wrong?
having the same issue
Hi @kevmittal,
Into BLACKLIST you probably have some regexp that match some urls that lead to a navigation request. As you stated those requests to not be handled by workbox's NavigationRoute, you need to handle their preloadResponse somehow. Otherwise they are cancelled.
Hi, little update from this on our site. This is our current setup, with which we still experience the error:
// these are the routes we want to cache (i.e. no navigation preload will be necessary for these)
const routes = getRoutes(shells, paths);
// we enable
navigationPreload.enable();
// we set up a navigation route catching all paths apart from the routes we are caching
const navigationRoute = new routing.NavigationRoute(new strategies.NetworkOnly(), {
blacklist: routes.map(route => {
return new RegExp(`/${language}-${country}/${route.path}`);
})
});
routing.registerRoute(navigationRoute);
// we register the routes we want to cache using StaleWhileRevalidate strategy
for (let i = 0; i < routes.length; i++) {
const staleWhileRevalidate = new strategies.StaleWhileRevalidate({ cacheName: routes[i].id });
const shellRegEx = `/${language}-${country}/${routes[i].shell}`;
const pathRegEx = new RegExp(`/${language}-${country}/${routes[i].path}`);
routing.registerRoute(pathRegEx, () => {
return staleWhileRevalidate.handle({ request: shellRegEx });
});
}
// this is where we tried following the advice from @astrinxit66 i.e. we'll handle the preload response for these whitelisted navigation routes by using a CacheFirst strategy (since we cache these using the StaleWhileRevalidate strategy above)
const navigationRouteForShells = new routing.NavigationRoute(new strategies.CacheFirst(), {
whitelist: routes.map(route => {
return new RegExp(`/${language}-${country}/${route.path}`);
})
});
routing.registerRoute(navigationRouteForShells);
we still see the The service worker navigation preload request was cancelled before 'preloadResponse' settled. If you intend to use 'preloadResponse', use waitUntil() or respondWith() to wait for the promise to settle. error in the console when visiting our cached paths. Works fine for non-cached paths. What are we missing or doing wrong? Any help appreciated!
Hi,
I've got workbox updated to 5.0.0, and still getting the "The service worker navigation preload request was cancelled" error even with navigationPreload switched off in GenerateSW with the following config:
module.exports.workboxWebpackPlugin = () => {
const PERIOD_1_DAY_IN_SEC = 60 * 60 * 24;
return new GenerateSW({
include: [],
skipWaiting: false,
cleanupOutdatedCaches: true,
navigationPreload: false,
sourcemap: false,
runtimeCaching: [
{
urlPattern: /\/i18n\/.*\.json$/,
handler: 'CacheFirst',
options: {
expiration: {
maxEntries: 1,
maxAgeSeconds: PERIOD_1_DAY_IN_SEC * 30
},
cacheName: 'dynamic',
cacheableResponse: {
statuses: [0, 200]
}
}
}
]
});
};
Does this mean the issue still reproducible in 5.0.0? Are there any workarounds?
@smolnikov, I can't think of any reason why you'd see that message if you don't have navigation preload enabled in the current version of your service worker. Are you sure that the new service worker has taken control of the current navigation when you see it? Can you reproduce it when you visit your web app in an Incognito window?
(FWIW, @philipwalton has been going through the workbox-core fetch() implementation and has, I believe, found a possible reason why this error might be cropping up when using the StaleWhileRevalidate strategy for navigation requests.)
happens to me as well with this configuration followed by https://developers.google.com/web/tools/workbox/guides/advanced-recipes#offline_page_only
const CACHE_NAME = 'offline-app';
const FALLBACK_HTML_URL = '/index.html';
precacheAndRoute(self.__WB_MANIFEST);
self.addEventListener('install', async (event) => {
await event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => cache.add(
new Request(FALLBACK_HTML_URL, {credentials: 'same-origin'}),
)),
);
});
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
skipWaiting();
}
});
navigationPreload.enable();
const navigationHandler = async (params) => {
try {
return await new NetworkFirst().handle(params);
} catch (error) {
return caches.match(FALLBACK_HTML_URL, {
cacheName: CACHE_NAME,
});
}
};
registerRoute(
new NavigationRoute(navigationHandler, {
denylist: [
/token-[^-]*\.json/,
/\.(?:map)$/,
],
}),
);
@philipwalton is there any update on this? We are also facing same issue
This is a bug in Chrome or in spec. You would see this not only when used Workbox, but in any website using ServiceWorkers Preloaded Response feature, like examples provided by spec, Google and Mozilla. For example https://developer.mozilla.org/en-US/docs/Web/API/NavigationPreloadManager and https://developers.google.com/web/updates/2017/02/navigation-preload will fail into same error.
Have anyone seen Chrome open issue for this? @jakearchibald?
Here chromium code pointing to this error message
https://chromium.googlesource.com/chromium/src/+/d894710be3b56a15871376c5979615053dddcd70/content/browser/service_worker/service_worker_browsertest.cc#418
const std::string kNavigationPreloadAbortError =
--
聽 | "The service worker navigation preload request was cancelled before "
聽 | "'preloadResponse' settled. If you intend to use 'preloadResponse', use "
聽 | "waitUntil() or respondWith() to wait for the promise to settle.";
https://bugs.chromium.org/p/chromium/issues/detail?id=1031950#c5
It finds out that the error was caused when skipped event.preloadResponse, for exampleaddEventListener("fetch", event => event.request.mode === "navigate" && new URL(event.request.url, location.origin).pathname !== "/test" && event.respondWith(event.preloadResponse) );will result error every time when accessing page /test
Maybe this helps to solve this workbox issue too.
Hey @jeffposnick, do you know if this issue has been solved with the new version of workbox, v6?
The change alluded to in https://github.com/GoogleChrome/workbox/issues/2178#issuecomment-592030941 has been implemented in Workbox v6.0.0 (when using StaleWhileRevalidate).
I'm not sure that it will resolve the issue in all its possible manifestations, but it is worth checking to see if you can reproduce it.
Hi! I ran into the same issue in workbox-webpack-plugin 6.0.2. Navigation preload never works.
sw.js:
import { precacheAndRoute, cleanupOutdatedCaches, addPlugins } from 'workbox-precaching';
import { skipWaiting, clientsClaim, setCacheNameDetails } from 'workbox-core';
import * as navigationPreload from 'workbox-navigation-preload';
import { ExpirationPlugin } from 'workbox-expiration';
import { CacheableResponsePlugin } from 'workbox-cacheable-response';
import { getClientConfig } from './utils/sentry.js';
navigationPreload.enable();
setCacheNameDetails({
prefix: 'mav-sw'
});
skipWaiting();
clientsClaim();
addPlugins([
new CacheableResponsePlugin({
statuses: [200]
}),
new ExpirationPlugin({
purgeOnQuotaError: true,
maxAgeSeconds: 30 * 24 * 60 * 60
})
]);
// eslint-disable-next-line no-underscore-dangle
const mainfest = self.__WB_MANIFEST;
precacheAndRoute(mainfest, { cleanURLs: false });
cleanupOutdatedCaches();
@lizryzhko, I think the issue with your setup is that you're enabling navigation preload but you don't have a runtime route setup that will actually end up using that preloaded response.
The example in the documentation shows the minimal usage scenario, where navigation preload is enabled and a route is registered that match navigation requests and response using a strategy that will read the preloaded response.
(Also, I would really suggest against using ExpirationPlugin alongside workbox-precaching. I don't think you're going to get the experience you expect, as workbox-precaching has its own mechanism for expiring entries. This makes me think we should prioritize https://github.com/GoogleChrome/workbox/issues/2600.)
Most helpful comment
having the same issue