I need to define my Service Worker as persistent in my Chrome extension because I'm using the webRequest API to intercept some data passed in a form for a specific request, but I don't know how I can do that. I've tried everything, but my Service Worker keeps unloading.
How can I keep it loaded and waiting until the request is intercepted?
WebSocket callbacks registered from within the chrome.runtime listener registrations of my extensions's service worker would not get invoked, which sounds like almost the same problem.
I approached this problem by making sure that my service worker never ends, by adding the following code to it:
function keepServiceRunning() {
setTimeout(keepServiceRunning, 2000);
}
keepServiceRunning()
After this, my callbacks now get invoked as expected.
If i understand correct you can wake up service worker (background.js) by alerts. Look at below example:
"permissions": [
"alarms"
],
chrome.alarms.create({ periodInMinutes: 4.9 })
chrome.alarms.onAlarm.addListener(() => {
console.log('log for debug')
});
Unfortunately this is not my problem and may be you have different problem too. When i refresh dev extension or stop and run prod extension some time service worker die at all. When i close and open browser worker doesn't run and any listeners inside worker doesn't run it too. It tried register worker manually. Fore example:
// override.html
<!DOCTYPE html>
<html lang="en">
<head>...<head>
<body>
...
<script defer src="override.js"></script>
<body>
<html>
// override.js - this code is running in new tab page
navigator.serviceWorker.getRegistrations().then((res) => {
for (let worker of res) {
console.log(worker)
if (worker.active.scriptURL.includes('background.js')) {
return
}
}
navigator.serviceWorker
.register(chrome.runtime.getURL('background.js'))
.then((registration) => {
console.log('Service worker success:', registration)
}).catch((error) => {
console.log('Error service:', error)
})
})
This solution partially helped me but it does not matter because i have to register worker on different tabs. May be somebody know decision. I will pleasure.
unlike the chrome.webRequest API the chrome.webNavigation API works perfectly because the chrome.webNavigation API can wake up the service worker, for now you can try putting the chrome.webRequest API api inside the chrome.webNavigation.
chrome.webNavigation.onBeforeNavigate.addListener(function(){
chrome.webRequest.onResponseStarted.addListener(function(details){
//.............
//.............
},{urls: ["*://domain/*"],types: ["main_frame"]});
},{
url: [{hostContains:"domain"}]
});
As Clairzil Bawon samdi's answer that chrome.webNavigation could wake up the service worker in MV3, here are workaround in my case:
// manifest.json
...
"background": {
"service_worker": "background.js"
},
"host_permissions": ["https://example.com/api/*"],
"permissions": ["webRequest", "webNavigation"]
...
In my case it listens onHistoryStateUpdated event to wake up the service worker:
// background.js
chrome.webNavigation.onHistoryStateUpdated.addListener((details) => {
console.log('wake me up');
});
chrome.webRequest.onSendHeaders.addListener(
(details) => {
// code here
},
{
urls: ['https://example.com/api/*'],
types: ['xmlhttprequest'],
},
['requestHeaders']
);
I found a different solution to keeping the extension alive. It improves on wOxxOm's answer by using a secondary extension to open the connection port to our main extension. Then both extensions try to communicate with each other in the event that any disconnects, hence keeping both alive.
The reason this was needed was that according to another team in my company, wOxxOm's answer turned out to be unreliable. Reportedly, their SW would eventually fail in an nondeterministic manner.
Then again, my solution works for my company as we are deploying enterprise security software, and we will be force installing the extensions. Having the user install 2 extensions may still be undesirable in other use-cases.