信息发布→ 登录 注册 退出

什么是Service Worker_如何使用它实现离线功能

发布时间:2026-01-06

点击量:
Service Worker 需手动注册、监听fetch并管理缓存策略,强制HTTPS(本地除外),常见错误包括MIME类型错误、scope缺失、未预缓存HTML等;离线能力取决于具体缓存逻辑实现。

Service Worker 是浏览器后台运行的脚本,能拦截网络请求、缓存资源、实现离线访问——但它不是“开箱即用”的离线开关,必须手动注册、监听 fetch 事件、并主动管理缓存策略。

Service Worker 必须通过 HTTPS 注册(本地开发除外)

浏览器强制要求:线上环境必须在 HTTPS *册 serviceWorker,否则 navigator.serviceWorker.register() 会直接失败并抛出 TypeError。localhost 和 127.0.0.1 被豁免,可本地调试。

常见错误现象:

  • Uncaught DOMException: Failed to register a ServiceWorker: The script has an unsupported MIME type ('text/html') —— 检查服务器是否返回了正确的 Content-Type: text/javascript
  • Uncaught (in promise) DOMException: Registration failed – no scope provided —— register() 的第二个参数 {scope: '...'} 缺失或路径不合法(scope 不能高于 service worker 文件所在目录)

注册后需手动监听 fetch 并决定缓存逻辑

注册成功 ≠ 自动离线。Service Worker 默认不缓存任何请求,你必须在 SW 脚本中监听 fetch 事件,并显式调用 caches.match()fetch()

典型缓存策略示例(优先读缓存,缓存未命中再发网络请求):

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

注意点:

  • caches.open('v1') 必须先调用,否则 caches.match() 返回 undefined
  • 静态资源(HTML/CSS/JS)建议在 install 事件中预缓存,避免首次 fetch 时缓存为空
  • fetch() 请求默认不带 cookies,如需认证,得加 {credentials: 'include'}

缓存更新机制容易被忽略:install → activate → cleanup 需手动触发

新版本 SW 文件部署后,旧版仍会持续控制页面,直到所有打开的页面关闭、或调用 skipWaiting() + clients.claim() 强制接管。

常见陷阱:

  • 修改了 SW 文件但页面没刷新,fetch 仍走旧逻辑 —— 检查 DevTools > Application > Service Workers 是否显示 “Waiting” 状态
  • 缓存名没升级(比如还用 'v1'),导致新 SW 读的是旧缓存 —— 每次变更缓存策略必须改 cacheName
  • 旧缓存没清理,磁盘越积越多 —— 在 activate 事件中遍历 caches.keys() 删除非当前版本缓存

离线功能依赖资源是否真正进缓存,而非“有 SW”

很多开发者以为注册了 SW 就能离线,结果发现 HTML 页面打不开——因为根路径 / 的 HTML 没被预缓存,而 SW 的 fetch 事件里又没对 HTML 做 fallback 处理。

实操建议:

  • install 阶段用 caches.addAll(['/', '/index.html', '/app.js']) 预加载关键资源
  • 对 HTML 请求单独 fallback 到 /offline.html(用 Response.redirect() 或构造 new Response(htmlString, {headers})
  • 动态资源(如 API)不适合全量缓存,应结合 stale-while-revalidate 策略,在 fetch 中判断 event.request.destination === 'json' 分流处理

离线能力不是靠 Service Worker 自身,而是靠你写的每一条 caches.put()、每一次 event.respondWith() 决定的。最容易被跳过的环节是缓存命名更新和 activate 清理,这两步漏掉,离线行为就会不可预测。

标签:# css  # javascript  # java  # html  # js  # json  # cookie  # 浏览器  # app  # ai  # red  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!