WEBKT

Service Worker 实战:离线缓存与推送通知快速上手

161 0 0 0

什么是 Service Worker?

Service Worker 本质上是一个在浏览器后台运行的 JavaScript 脚本,它可以拦截网络请求、缓存资源、推送通知,即使在用户关闭网页后也能继续运行(部分功能)。这使得我们可以实现离线访问、消息推送等功能,极大地提升用户体验。

Service Worker 的生命周期

Service Worker 的生命周期包括:

  1. 注册(Register):在网页中注册 Service Worker。
  2. 安装(Install):Service Worker 首次安装时触发,通常用于缓存静态资源。
  3. 激活(Activate):Service Worker 安装完成后激活,可以清理旧的缓存。
  4. 运行(Running):Service Worker 拦截网络请求,处理推送通知等。

离线缓存实现

1. 注册 Service Worker

在你的 HTML 文件中,添加以下代码注册 Service Worker:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js')
    .then(function(registration) {
      console.log('Service Worker 注册成功,范围:', registration.scope);
    })
    .catch(function(error) {
      console.log('Service Worker 注册失败:', error);
    });
}

2. 创建 sw.js 文件

在你的网站根目录下创建一个名为 sw.js 的文件,用于编写 Service Worker 的逻辑。

3. 缓存静态资源

sw.js 文件中,监听 install 事件,缓存静态资源:

const CACHE_NAME = 'my-site-cache-v1';
const urlsToCache = [
  '/',
  '/index.html',
  '/style.css',
  '/script.js',
  '/image.png'
];

self.addEventListener('install', function(event) {
  // 执行安装步骤
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('已打开缓存');
        return cache.addAll(urlsToCache);
      })
  );
});

4. 拦截网络请求并从缓存返回

监听 fetch 事件,拦截网络请求,如果缓存中存在对应的资源,则直接返回缓存中的资源:

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        // 缓存命中 - 返回 response
        if (response) {
          return response;
        }

        // 未在缓存中找到 - 使用 fetch
        return fetch(event.request);
      }
    )
  );
});

5. 更新缓存

当网站资源更新时,我们需要更新缓存。监听 activate 事件,清理旧的缓存:

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

  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

推送通知实现

1. 获取推送权限

在你的 JavaScript 代码中,请求用户授权推送通知:

function subscribePush() {
  navigator.serviceWorker.ready.then(function(registration) {
    registration.pushManager.subscribe({
      userVisibleOnly: true,
      applicationServerKey: 'YOUR_PUBLIC_VAPID_KEY' // 替换为你的 VAPID 公钥
    })
    .then(function(subscription) {
      console.log('用户已订阅:', subscription);
      // 将 subscription 发送到服务器
    })
    .catch(function(error) {
      console.error('订阅失败:', error);
    });
  });
}

注意: 你需要生成一对 VAPID 密钥(公钥和私钥)用于安全地推送通知。可以使用在线工具或 Node.js 库生成。

2. 监听 push 事件

sw.js 文件中,监听 push 事件,当收到推送通知时显示通知:

self.addEventListener('push', function(event) {
  const payload = event.data ? event.data.text() : '没有内容';

  event.waitUntil(
    self.registration.showNotification('推送通知', {
      body: payload,
      icon: '/icon.png'
    })
  );
});

3. 服务器端推送

你需要一个服务器端脚本来发送推送通知。使用 VAPID 私钥对请求进行签名,并将推送消息发送到 Google Cloud Messaging (GCM) 或 Firebase Cloud Messaging (FCM) 等推送服务。

示例总结

以上代码提供了一个简单的 Service Worker 实现离线缓存和推送通知的示例。你需要根据你的具体需求进行修改和扩展。例如,可以添加更复杂的缓存策略、处理不同类型的推送消息等。

注意事项

  • HTTPS: Service Worker 只能在 HTTPS 环境下运行。
  • 调试: 使用 Chrome 开发者工具的 Application 面板可以方便地调试 Service Worker。
  • VAPID 密钥安全: 妥善保管你的 VAPID 私钥,不要泄露给他人。

希望这个简单的示例能帮助你快速上手 Service Worker,并将其应用到你的项目中!

码农小李 Service Worker离线缓存推送通知

评论点评