简体   繁体   中英

location.reload(true) is not working correctly for PWA

I have a web app, and recently converted it into a PWA, so I'm new to service workers and pwa in general. Hoping someone has gone through what I'm facing, but I have not found anything on StackOverflow or Google after searching for the last few days.

My web app uses AJAX to post content and on success do a location.reload(true) to show the latest content (or provides access to new page content) at the same scroll point.

However once I created the PWA, the location.reload(true) seems to be loading cached content. Is there any way to get this to work with fresh content from the server?

I checked that this is only behaving this way for iOS PWA/iOS Safari and Android PWA/ Android Chrome. The location.reload is still working for Firefox/Chrome mobile web for iOS and Firefox for Android (iOS Safari and Android Chrome was behaving correctly before the PWA conversion).

Here's my service worker:

var cacheName = 'dev-pwa';
var filesToCache = [
  '/',
  'index.php',
  'style.css',
  'js/main.js'
];

/* Start the service worker and cache all of the app's content */
self.addEventListener('install', function(e) {
  e.waitUntil(
    caches.open(cacheName).then(function(cache) {
      return cache.addAll(filesToCache);
    })
  );
});

/* Serve cached content when offline */
self.addEventListener('fetch', function(e) {
  e.respondWith(
    caches.match(e.request).then(function(response) {
      return response || fetch(e.request);
    })
  );
  
  e.waitUntil(update(e.request));
  
});


function update(request) {
  return caches.open(cacheName).then(function (cache) {
    return fetch(request).then(function (response) {
      return cache.put(request, response);
    });
  });
}

Your implementation of the service worker strategy is slightly flawed. But don't worry, it's an easy fix. :)

Actually, what you are doing is serving the content using cache falling back to the network strategy (with a slightly flawed* implementation), but rather what you want to use is either network falling back to the cache or cache then network (recommended) strategy. The latter will serve the content from cache immediately and then update the content as soon as the latest response is available via the n/w call. The links already have the sample code snippets, so avoiding adding them here explicitly.

* Your e.waitUntil(update(e.request)) does seem to be updating the cache but it will be reflected only in the subsequent fetch attempt since in the first pass, you are still serving the originally cached content and in parallel updating the cache (please note, this is not what is read immediately though, since you've already read the cache content via e.respondWith(caches.match(e.request).then(function(response) {return response || fetch(e.request); and then called your "update" method to refresh the cache), which is kind of defeating the purpose and making your cache fetch even slower than intended, since it now has to wait for the network call to be completed anyway and update the cache, which is not even used in this current read request.

EDIT : Also consider reading the SO thread on Can Service Workers Cache POST Request . Hence, apart from correcting the strategy as mentioned above, you might have to use some workarounds for caching the POST content.

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