簡體   English   中英

PWA 在 Safari 發布新版本后一直顯示舊版本

[英]PWA keeps showing the old version after a new release on Safari

我基於 ReactJs 和 nextJs 將 PWA 和 service worker 添加到我現有的 web 應用程序中。 第一次發布時一切看起來都很好。 但是,當我嘗試發布更新時,發生了一些奇怪的事情。

每次發布后,我都會收到一條提醒,要求我更新到新版本。

但是,當最終出現新版本時,我的應用程序會更新,但在我關閉並重新打開它后它會再次退回到舊版本。

應該注意的是,這只發生在某些手機上。

請幫我解決。

我的軟件:

navigator.serviceWorker
        .getRegistrations()
        .then(function (registrations) {
                return Promise.all(registrations.map(function(r) {return r.unregister()}));
            })
        .then(function() {
                return navigator.serviceWorker.register(serviceFilePath, {
                            scope: _this.options.scope
                }).then(function (registration) {
                    console.info("Service worker has been registered for scope: " + registration.scope);
                    if (needsUpdate) {
                            return registration.update().then(function () {
                            _this.reload();
                            window.parent.postMessage("new-version", "*");
                            console.info("Service worker has been updated.");
                            window.location.reload();
                            return true;
                });
            }
            return true;
        });
});


ServiceWorker.prototype.reload = function () {
            var _this = this;
            return this.getOptions(true).then(function (options) {
                return Promise.all([
                    _this.preload(),
                    // _this.checkPersistence(),
                    _this.checkPushServiceStatus(false)
                ]).then(function () {
                    _this.debug("Clear old caches... (< v" + options.version + ")");
                    var promises = [];
                    for (var i = 0; i < options.version; i++) {
                        promises.push(new AdvancedServiceWorker.BrowserCache(options.storageName, i).remove());
                    }
                    return Promise.all(promises).then(function () {
                        return true;
                    });
                });
            }).catch(function () {
                return false;
            });
        };
        
        
        
BrowserCache.prototype.remove = function (condition) {
            if (!condition) {
                return caches.delete(this.storageName);
            } else if (typeof condition === "string" ||
                condition instanceof String ||
                condition instanceof RegExp) {
                if (!(condition instanceof RegExp)) {
                    condition = AdvancedServiceWorker.Condition.wildCardToRegEx((condition));
                }
                return this.open().then(function (cache) {
                    return cache.keys().then(function (keys) {
                        var promises = [];
                        keys.forEach(function (request) {
                            if (request.url && condition.test(request.url)) {
                                promises.push(cache.delete(request));
                            }
                        });
                        if (!promises.length) {
                            return Promise.resolve(false);
                        }
                        return Promise.all(promises).then(function (results) {
                            for (var i = 0; i < results.length; i++) {
                                if (results[i]) {
                                    return true;
                                }
                            }
                            return false;
                        }, function () {
                            return false;
                        });
                    });
                });
            } else if (condition instanceof Array && condition.length) {
                return this.open().then(function (cache) {
                    var promises = [];
                    for (var i = 0; i < condition.length; i++) {
                        promises.push(cache.delete((condition[i])));
                    }
                    return Promise.all(promises).then(function (results) {
                        for (var j = 0; j < results.length; j++) {
                            if (results[j]) {
                                return true;
                            }
                        }
                        return false;
                    }, function () {
                        return false;
                    });
                });
            } else {
                return Promise.resolve(false);
            }
        };

好的,下面是我的服務人員。

需要考慮的一些事情,因為這是我根據自己的需要制作的軟件,因此您可能需要根據自己的需要進行調整。

它旨在為一個簡單的 SPA 工作,在頁面加載時加載它的所有資源。 一般來說,這是大多數 SPA 的工作方式。 但是如果你有你說通過fetch等動態加載的資源,你會想要使用cache.addAll手動添加這些文件,一些 JS 框架會動態加載路由,所以請注意。

因為我是自動加載資源而不是在理論上使用addAll你可能有一個離線應用程序沒有完全加載它的所有資源,例如。 如果您在更新期間碰巧丟失了 inte.net。 實際上這不太可能,如果發生這種情況,簡單的刷新就可以解決,但是如果您確實想確保所有內容都已加載,則必須使用cache.addAll手動添加它們,請參閱文件中的注釋以了解是否這樣做。

足夠的解釋,這是代碼。 -> ps,它在這里也使用 Typescript,但您可以通過刪除第一行的聲明輕松刪除它。 (我只是喜歡我的類型)。

declare var self: ServiceWorkerGlobalScope;

//remember to update version number if updating.
const cacheName = "my-spa-v1.0.0";

self.addEventListener("install", (e) => {
  e.waitUntil(
    (async () => {
      const cache = await caches.open(cacheName);
      //if you want to manually add resources
      //await cache.addAll([contentToCache,...]);
      return self.skipWaiting();
    })()
  );
});

//lets keep our cache's clean
self.addEventListener("activate", (e) => {
  e.waitUntil(
    caches.keys().then((keyList) => {
      return Promise.all(
        keyList.map((key) => {
          if (key === cacheName) {
            return;
          }
          return caches.delete(key);
        })
      );
    })
  );
});

//lets auto cache GET requests
self.addEventListener("fetch", (e) => {
  e.respondWith(
    (async () => {
      const r = await caches.match(e.request);
      if (r) {
        return r;
      }
      const response = await fetch(e.request);
      const cache = await caches.open(cacheName);
      if (e.request.method === 'GET')
        cache.put(e.request, response.clone());
      return response;
    })()
  );
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM