I have a rather quirky Firefox behavior, I can’t explain. Imagine those two very simple HTML tags:
<img src="http://localhost:1234/api/getBlob/1">...
<video src="http://localhost:1234/api/getBlob/2">...
I wrote a service worker that adds the JWT to the Authorization
Header as my backend isn’t public.
self.addEventListener('fetch', function (event) {
const url = event.request.url.toLowerCase();
if (!url.includes('api/getblob')) {
return;
}
if (event.request.headers.has('Authorization')) {
return;
}
event.respondWith(
(async function () {
const token = await requestTokenFromMainThread();
const headers = new Headers(event.request.headers);
headers.set('Authorization', 'Bearer ' + token);
const modifiedRequestInit = {
headers: headers,
mode: 'cors',
credentials: 'omit',
};
const modifiedRequest = new Request(event.request, modifiedRequestInit);
try {
return fetch(modifiedRequest);
} catch (error) {
console.error('Error fetching resource:', error);
return new Response('Error fetching resource', { status: 500 });
}
})(),
);
});
function requestTokenFromMainThread() {
return new Promise((resolve) => {
const channel = new MessageChannel();
channel.port1.onmessage = (event) => {
resolve(event.data);
};
self.clients.matchAll().then((clients) => {
if (clients && clients.length) {
clients[0].postMessage('requestToken', [channel.port2]);
}
});
});
}
This works great with Safari and Chromium-based browsers (like Edge or Chrome itself). But it starts to get quirky with Firefox. While <img src
is handled by the service worker, <video src
isn’t and I never ever land inside the fetch function. So I put a debug point at const url = event.request.url.toLowerCase();
this will never be hit with a <video src
but will be hit with <img src
, and I am not sure why.
EDIT 1:
In Firefox, if I go to the request in question and click “Use as fetch in console” – then, as almost expected, it works like a charm.