登录
首页 >  文章 >  前端

ServiceWorker是什么?如何实现离线应用?

时间:2026-01-25 20:15:41 312浏览 收藏

学习文章要努力,但是不要急!今天的这篇文章《JavaScript的Service Worker是什么?如何实现离线应用?》将会介绍到等等知识点,如果你想深入学习文章,可以关注我!我会持续更新相关文章的,希望对大家都能有所帮助!

Service Worker 需HTTPS/localhost环境、页面重载后才生效,且SW文件须同源并可缓存;通过install预缓存、fetch拦截实现离线访问;fetch响应需clone才能复用;更新依赖skipWaiting与clients.claim。

什么是javascript的Service Worker_如何实现离线应用?

Service Worker 是浏览器后台运行的脚本,它能拦截网络请求、缓存资源、实现离线访问——但它不是全局可用的,必须满足 HTTPS(或 localhost)环境,且注册后不会自动接管页面

Service Worker 为什么不能直接用 navigator.serviceWorker.register() 就生效?

注册只是告诉浏览器“有这么个文件”,真正生效需要两个条件同时满足:

  • 页面已通过 https://http://localhost 加载(file:// 协议完全不支持)
  • Service Worker 脚本注册成功后,必须重新加载页面(或等待当前页面关闭再打开),才能被该页面控制
  • Service Worker 文件本身需与页面同源,且响应头不能含 Cache-Control: no-store 等禁止缓存的指令(否则浏览器可能反复拉取新版本失败)

如何用 cache.addAll()fetch 事件实现基础离线能力?

核心逻辑是:安装阶段预缓存关键资源;运行时对匹配 URL 的请求优先返回缓存,未命中再走网络。注意 cache.addAll() 只接受相对路径(相对于 SW 文件位置),且会因任一资源失败而整体拒绝 Promise。

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open('v1').then(cache =>
      cache.addAll([
        '/',
        '/index.html',
        '/styles/main.css',
        '/scripts/app.js'
      ])
    )
  );
});

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

为什么 fetch() 返回的 Response 不能直接 put() 到 Cache?

因为 fetch() 返回的 Response 流体(ReadableStream)只能读取一次。若想既返回给页面又存入缓存,必须用 response.clone() 分出副本:

  • 不 clone 直接 cache.put(req, res) → 第二次读取时报错 TypeError: Failed to execute 'put' on 'Cache': Request body is already used
  • 正确做法是:cache.put(req, res.clone()),然后用原 res 响应页面
  • 也别忘了检查 res.ok,避免把 404/500 错误页也缓存进去

离线应用真正的难点不在缓存,而在更新策略和生命周期控制

用户刷新页面时,浏览器可能还在用旧版 Service Worker,即使你已部署新 SW 文件。它只会在下次导航时静默下载并进入 waiting 状态——除非你主动调用 skipWaiting(),或让用户点击“刷新”触发 clients.claim()。这些细节不处理,离线功能看似正常,实则长期无法更新缓存内容。

终于介绍完啦!小伙伴们,这篇关于《ServiceWorker是什么?如何实现离线应用?》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布文章相关知识,快来关注吧!

前往漫画官网入口并下载 ➜
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>