使用 Service Worker 实现 H5 离线缓存

使用 Service Worker 实现 H5 离线缓存
最新回答
奶茶

2020-09-04 02:18:32

使用 Service Worker 实现 H5 离线缓存的核心是通过后台脚本管理缓存资源,拦截网络请求并提供离线支持。以下是具体实现步骤和关键代码说明:

实现原理

Service Worker 通过四个阶段实现离线缓存:

  1. 安装阶段:加载并执行脚本,初始化缓存并存储静态资源(如 HTML、CSS、JS)。
  2. 激活阶段:控制网络请求,清理旧缓存,为新版本 Service Worker 准备环境。
  3. 网络请求拦截:监听所有请求,优先从缓存返回资源,若无缓存则发起网络请求。
  4. 更新阶段:检测新脚本时触发更新,替换缓存或执行迁移操作。
优势
  • 离线可用性:用户断网时可访问已缓存内容。
  • 性能优化:缓存静态资源减少重复加载,提升加载速度。
  • 节省流量:优先使用缓存,减少数据传输。
  • 安全性:避免断网时 CSRF 等攻击风险。
实现步骤1. 创建 Service Worker 脚本文件

新建 sw.js,定义生命周期事件处理程序:

// 缓存名称const CACHE_NAME = 'my-cache-v1';// 需缓存的资源列表const urlsToCache = [ '/', '/index.html', '/styles.css', '/scripts.js', '/images/logo.png'];// 安装阶段:初始化缓存self.addEventListener('install', (event) => { event.waitUntil( caches.open(CACHE_NAME) .then((cache) => cache.addAll(urlsToCache)) );});// 激活阶段:清理旧缓存self.addEventListener('activate', (event) => { event.waitUntil( caches.keys().then((cacheNames) => { return Promise.all( cacheNames.map((cacheName) => { if (cacheName !== CACHE_NAME) { return caches.delete(cacheName); } }) ); }) );});// 拦截请求:优先返回缓存self.addEventListener('fetch', (event) => { event.respondWith( caches.match(event.request) .then((response) => { // 缓存命中则返回,否则发起网络请求 return response || fetch(event.request); }) );});2. 注册 Service Worker

在 index.html 中注册脚本,确保作用域覆盖目标页面:

<script> if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/sw.js') .then((registration) => { console.log('ServiceWorker 注册成功:', registration.scope); }) .catch((error) => { console.log('ServiceWorker 注册失败:', error); }); }); }</script>关键代码解析
  • caches.open():打开或创建指定名称的缓存。
  • cache.addAll():批量添加资源到缓存。
  • caches.keys():获取所有缓存名称,用于清理旧版本。
  • caches.match():检查请求是否存在于缓存中。
  • event.respondWith():拦截请求并自定义响应逻辑。
注意事项
  1. 作用域限制:Service Worker 仅能控制注册路径下的子路径资源。
  2. HTTPS 要求:本地开发可用 localhost,生产环境必须部署 HTTPS。
  3. 缓存策略:根据需求选择策略(如缓存优先、网络优先)。
  4. 更新机制:修改 CACHE_NAME 或文件内容可触发更新。
扩展优化
  • 动态缓存:在 fetch 事件中缓存动态资源(如 API 响应)。
  • 缓存过期:通过版本号或时间戳管理缓存生命周期。
  • 后台同步:结合 Backgroud Sync 实现断网时暂存请求,联网后重试。

通过上述步骤,可实现一个基础的 H5 离线缓存系统,显著提升用户体验和数据安全性。