Issue
I have a service worker that I use to enable an offline version of my website. This works great. I also have an Android app that is basically just a wrapper around a webview that loads my website.
All was fine and dandy until about 2-3 weeks ago when the Fetch() request started immediately failing. It is only failing when running through the Android webview. Running through a browser works fine. If the resource is cached already (i.e. via the install event) then it works great, it's only when I get a page that is not cached.
The code in my service worker:
self.addEventListener("fetch", function (event) {
if (event.request.method !== 'GET'
|| event.request.url.toLowerCase().indexOf('//ws') > -1
|| event.request.url.toLowerCase().indexOf('localws') > -1) {
// Don't intercept requests made to the web service
// If we don't block the event as shown below, then the request will go to
// the network as usual.
return;
}
event.respondWith(async function () {
// override the default behavior
var oCache = await caches.open('cp_' + version);
var cached = await oCache.match(event.request.url);
if (cached && cached.status < 300) {
return cached;
}
// Need to make a call to the network
try {
var oResp = await fetch(event.request); // THIS LINE CAUSES THE PROBLEM!!!
return oResp;
} catch (oError) {
console.log('SW WORKER: fetch request to network failed.', event.request);
return new Response('<h1>Offline_sw.js: An error has occured. Please try again.</h1><br><h2>Could not load URL: ' + event.request.url + '</h2>', {
status: 503,
statusText: 'Service Unavailable',
headers: new Headers({
'Content-Type': 'text/html'
})
});
}
}()); // event.respondwith
}); // fetch
The line:
var oResp = await fetch(event.request);
is called once I've determined it is not cached and seems to be the culprit. When it errors out I get the following error in my catch(): 'Failed to fetch'
This seems pretty generic and not helpful. Again, this works when going through a browser and so I know it's not a CORS issue, service worker in the wrong directory, etc. Again, it worked until about 3 weeks ago and now I'm getting reports from customers that it's not working.
Here's a screen shot of the actual event.request that I'm sending off:
In the chrome developer tools (used to debug the webview) I see the following:
Am I doing something wrong or is this a bug in the webview / chrome that was released recently? (I say that as chrome powers the webview)
Solution
Looks like it was a bug in chromium. See bugs.chromium.org/p/chromium/issues/detail?id=977784. Should be fixed in v 76.
As a work around (as the link mentioned), you can add the following to your android code:
ServiceWorkerController oSWController = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
oSWController = ServiceWorkerController.getInstance();
oSWController.setServiceWorkerClient(new ServiceWorkerClient(){
@Nullable
@Override
public WebResourceResponse shouldInterceptRequest(WebResourceRequest request){
return super.shouldInterceptRequest(request);
}
});
}
Answered By - ScottR



0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.