简体   繁体   中英

PWA offline mode not loading from cache on mobile browsers

I wrote a simple PWA ( current version ) based on this tutorial by Vaadin . It works fine, tested in Chrome, also in offline mode.

By using it on a mobile device, issues occur:

  • After saving the PWA, starting it once, it runs fine.
  • then after closing, turning on flight mode and restarting the PWA, I get a system message, saying I have no internet connection -> no problem, I can ignore that
  • after ignoring, the app does not load the static assets as I expected it, but shows a blank page, saying the browser could not load the page, since I don't have internet connection.

I thought that is, what the PWA is good for? Why does it not load the static assets? I think my service-worker is just fine:

const staticAssets = [
    './',
    './styles.css',
    './app.js',
    './images',
    './fallback.json',
    './images/system/offline.png'
]



self.addEventListener('install', async event => {
    const cache = await caches.open('static-assets');
    cache.addAll(staticAssets);
});

self.addEventListener('fetch', event => {
    const req = event.request;
    const url = new URL(req.url);

    if(url.origin === location.origin){
        event.respondWith(cacheFirst(req));
    }else{
        event.respondWith(networkFirst(req));
    }

});


async function cacheFirst(req){
    const cachedResponse = await caches.match(req);
    return cachedResponse || fetch(req);
}

async function networkFirst(req){
    const cache = await caches.open('dynamic-content');
    try{
        const res = await fetch(req);
        cache.put(req, res.clone());
        return res;
    }catch(err){
        const cachedResponse = await cache.match(req);
        return cachedResponse || caches.match('./fallback.json');
    }
}

I'm happy to share more code, if you think the problem is somewhere else!

I had the same issue. In my case, the issue came from the manifest adding a query string to the start_url. The cache is sensitive to this. You can add an argument to .match in order to prevent it, like this:

caches.match(event.request, {ignoreSearch: true})

The problem was within the service-worker:

I forgot to add the service worker file to the static assets.

Found the solution by reading the answers of this question: https://stackoverflow.com/a/44482764/7350000 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM