📜  添加更新反应 pwa 功能 - Javascript (1)

📅  最后修改于: 2023-12-03 15:40:46.762000             🧑  作者: Mango

添加更新反应 PWA 功能 - JavaScript

Progressive Web Apps (PWA) 是具有本地应用程序体验的 Web 应用程序。在许多方面,它们就像本机应用程序,可以安装、具有应用程序图标和离线工作。

在本文中,我们将讨论如何添加更新反应功能以确保您的 PWA 总是最新的。

什么是更新反应?

更新反应是指在用户访问站点时,立即提供最新版本的站点内容。这意味着您的 PWA 将始终具有最新的功能和修复程序,而无需用户手动更新。

如何实现更新反应?

在实现更新反应之前,您需要确保您的 PWA 具有以下功能:

  • Service Worker:它是 PWA 的核心组件,它可以让您控制网络请求并缓存您的应用程序内容。
  • Manifest 文件:它是 Web 应用程序的清单,其中包含一些元数据和图标,以供 Web 应用程序在本机应用程序中使用。
步骤 1 - 注册 Service Worker

要注册 Service Worker,您需要创建一个 JavaScript 文件并将其存储在您的项目根目录中。在该文件中,添加以下代码:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js')
      .then((registration) => {
        console.log('Service Worker registered with scope:', registration.scope);
      }, (error) => {
        console.log('Service worker registration failed:', error);
      });
  });
}

该代码将注册您的 Service Worker,并在注册成功后将“Service Worker registered with scope”消息记录到控制台。

步骤 2 - 编写 Service Worker

在您的 Service Worker 文件中,添加以下代码:

const CACHE_NAME = 'pwa-cache-v1';

const urlsToCache = [
  '/',
  '/index.html',
  '/styles.css',
  '/app.js',
  '/manifest.json',
  '/images/icon-192x192.png',
  '/images/icon-512x512.png'
];

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then((cache) => cache.addAll(urlsToCache))
      .then(() => {
        console.log('Cache initialized.');
      })
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then((response) => response || fetch(event.request))
  );
});

该代码将缓存 PWA 的所有静态文件和清单文件,并在 fetch 事件中使用缓存。

步骤 3 - 添加更新反应逻辑

现在,您需要在 Service Worker 中添加更新反应逻辑,以确保 PWA 始终具有最新的版本。

self.addEventListener('activate', (event) => {
  const cacheWhitelist = [CACHE_NAME];

  event.waitUntil(
    caches.keys().then((cacheNames) => Promise.all(
      cacheNames.map((cacheName) => {
        if (!cacheWhitelist.includes(cacheName)) {
          return caches.delete(cacheName);
        }
      })
    ))
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then((response) => {
        if (response) {
          return response;
        }

        const fetchRequest = event.request.clone();

        return fetch(fetchRequest).then((response) => {
          if (!response || response.status !== 200 || response.type !== 'basic') {
            return response;
          }

          const responseToCache = response.clone();

          caches.open(CACHE_NAME).then((cache) => {
            cache.put(event.request, responseToCache);
          });

          return response;
        });
      })
  );
});

该代码会在 activate 事件中删除旧缓存,并在 fetch 事件中检查响应是否为最新版本。如果是,它将返回缓存的响应。否则,它将使用 fetch 强制获取最新的响应,并将其缓存到新的缓存中。

步骤 4 - 添加“更新可用”的通知

为了向用户显示新版本可用的通知,您需要在 Service Worker 中使用 self.registration.showNotification 方法。添加以下代码:

self.addEventListener('message', (event) => {
  if (event.data === 'skipWaiting') {
    self.skipWaiting();
  }
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request)
      .then((response) => {
        if (response) {
          return response;
        }

        const fetchRequest = event.request.clone();

        return fetch(fetchRequest).then((response) => {
          if (!response || response.status !== 200 || response.type !== 'basic') {
            return response;
          }

          const responseToCache = response.clone();

          caches.open(CACHE_NAME).then((cache) => {
            cache.put(event.request, responseToCache);
          });

          // Add this code to check for latest version
          self.registration.showNotification('New version available', {
            body: 'Please refresh the page to use the latest version.',
            actions: [
              {
                action: 'refresh',
                title: 'Refresh'
              }
            ]
          });

          return response;
        });
      })
  );
});

self.addEventListener('notificationclick', (event) => {
  event.notification.close();

  if (event.action === 'refresh') {
    event.waitUntil(
      caches.keys().then((cacheNames) => Promise.all(
        cacheNames.map((cacheName) => {
          if (CACHE_NAME !== cacheName) {
            return caches.delete(cacheName);
          }
        })
      ))
      .then(() => {
        self.clients.claim();
        location.reload();
      })
    )
  }
});

该代码将在新版本可用时向用户显示通知,并在用户单击通知上的刷新按钮时刷新页面。

总结

在本文中,您已学习了如何为您的 PWA 添加更新反应功能。通过使用 Service Worker 和 Manifest 文件,以及添加更新反应逻辑和通知,您的 PWA 现在将具有最新的版本,而无需用户手动更新。