0

0

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

幻影之瞳

幻影之瞳

发布时间:2026-01-06 20:02:39

|

109人浏览过

|

来源于php中文网

原创

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

什么是service worker_如何使用它实现离线功能

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);
    })
  );
});

注意点:

飞书多维表格
飞书多维表格

表格形态的AI工作流搭建工具,支持批量化的AI创作与分析任务,接入DeepSeek R1满血版

下载
  • 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 清理,这两步漏掉,离线行为就会不可预测。

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

547

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

373

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

729

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

471

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

394

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

990

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

655

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

550

2023.09.20

PPT动态图表制作教程大全
PPT动态图表制作教程大全

本专题整合了PPT动态图表制作相关教程,阅读专题下面的文章了解更多详细内容。

13

2026.01.07

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.7万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.8万人学习

CSS教程
CSS教程

共754课时 | 18.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号