I am hosting a font from the same website that uses it (i.e. same origin) and I stumbled upon something strange while implementing my caching strategy inside the app's service worker.
Fetch requests for fonts (i.e. request.destination === 'font'
) have a value of 'cors'
for their mode
property, which is strange considering that the font is downloaded from the same origin it's being hosted.
Website structure
- /index.html
- /font.woff2
- /image.svg
- /sw.js
The issue
Locally-hosted font is requested by the app from the same origin but when the service worker intercepts the network request for the font, the underlying Request has mode === 'cors'
, despite being served from the same origin.
HTML code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Font cors test</title>
<style>
@font-face {
font-family: 'Comfortaa';
font-style: normal;
font-weight: 300 700;
font-display: swap;
src: url('/Comfortaa-Variable.woff2') format('woff2-variations');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
html {
font-family: Comfortaa, sans-serif;
}
body {
width: 100vw;
position: relative;
display: grid;
place-content: center;
}
h1 {
color: salmon;
text-align: center;
}
</style>
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.catch( function ( err ) {
console.error('Failed to register service worker:', err.stack);
});
});
}
</script>
</head>
<body>
<h1>Hi there!</h1>
<img src="/patrick.svg" alt="Patrick Star">
</body>
</html>
Service worker code
self.addEventListener('fetch', (event) => {
console.debug('=============================================');
console.debug('Service worker fetch request:');
console.debug(event.request);
console.debug('URL:', event.request.url);
console.debug('DESTINATION:', event.request.destination);
console.debug('MODE:', event.request.mode);
});
Steps to reproduce
- Visit test site.
- Open console in dev tools.
- Refresh page so that requests go through service worker (installed & activated in step 1).
Observed behavior
Two resources are fetched from the same origin, one image file, one font file:
- Image request has
mode === 'no-cors'
as expected.
- Font has
mode === 'cors'
despite being downloaded from the same origin.
I've been looking at the spec for font fetching requirements but cannot see why this would be the case.
The reason I ask is because I've been using Request.mode
to decide which assets to cache and which ones I should not and this issue breaks my caching heuristic, forcing me to give special treatment to fonts for no apparent reason.
Any clarification would be much appreciated.