跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

html制作SW缓存策略选择_html Service Worker缓存优先网络优先【方法】

缓存优先策略必须在 fetch 事件中显式调用 caches.match() 并用 event.respondWith() 包裹,install 阶段仅预存资源无效;需处理匹配失败回退、activate 清理旧缓存、response.clone() 避免流耗尽。 缓存优先策略必须在 fetch 事件里手动 match,不是 install 阶段加了就生效 很多人注册完
sw.js
、在
install
阶段调了
caches.addAll()
,就以为“缓存优先”自动跑起来了——其实完全没拦截请求。Service Worker 不会默认把缓存当第一响应源,必须在
fetch
事件中显式调用
caches.match(event.request)
并用
event.respondWith()
包裹整个逻辑链。 常见错误现象: 页面刷新后仍发网络请求,DevTools Network 面板看到 status 200 而非 from cache 断网时白屏或报错,而不是返回缓存的 HTML
caches.match()
返回
undefined
,但代码没处理 fallback,直接 return 了空值 实操建议: 每个
fetch
监听器开头必须写
event.respondWith(...)
,否则浏览器走默认流程
caches.match()
是 Promise,要用
.then()
处理结果,不能直接
if (response) return response
匹配不到时,务必接一个
fetch(event.request)
回退,否则请求直接失败 哪些请求适合缓存优先?哪些绝对不能缓存 缓存优先只对特定请求有效,盲目套用会导致数据错乱或命中率极低。 立即学习 “ 前端免费学习笔记(深入) ”; 适用场景(推荐缓存优先): 静态资源:HTML 入口页(如
'/index.html'
)、带哈希的 CSS/JS(如
'/js/app-8a3b2c.js'
)、图标、字体 同源、可克隆(
response.type === 'basic'
)、GET 方法的请求 不带查询参数的路径;若必须带参(如
/api/config?env=prod
),需提前 normalize URL 或用
ignoreSearch: true
禁止缓存优先的场景: 使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件 如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Andr​​oid友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Andr​​oid应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更 下载 带敏感参数的接口:
'/api/user?token=abc123'
、
'/auth/login'
——
caches.match()
按完整 URL 匹配,不同 token 就是不同 key,缓存爆炸且不安全 POST / PUT / DELETE 请求:Cache API 不支持缓存非 GET 请求的响应 动态 HTML(如服务端渲染的个人中心页):内容实时变化,缓存优先会返回过期信息 activate 阶段不清理旧缓存,设备存储会悄悄爆掉 每次更新
sw.js
,如果只改了
cache_name
(比如从
'v1'
改成
'v2'
),旧缓存不会自动消失。用户用几个月后,
caches.keys()
可能返回十几个历史版本,占用几十 MB 存储,且
caches.match()
可能意外命中错误版本。 实操建议: 在
activate
事件中调用
caches.keys().then(keys => Promise.all(keys.filter(k => k !== CURRENT_CACHE_NAME).map(k => caches.delete(k))))
不要在
activate
里做
cache.keys()
+ 逐条
match()
检查——太慢,可能被浏览器中断 搭配
self.clients.claim()
,确保新 SW 立即接管当前页面,避免新旧缓存混用 调试时可在 DevTools > Application > Cache Storage 手动删缓存,验证清理逻辑是否生效 response.clone() 不是可选项,是必选项
Response
对象的 body 是一个 ReadableStream,只能被读取一次。如果你在缓存写入前没 clone,
cache.put(request, response)
会消耗流,导致后续
return response
报错
TypeError: Failed to execute 'clone' on 'Response': Response body is already used
或直接返回空响应。 正确写法永远是:
fetch(event.request).then(networkResponse => { if (networkResponse && networkResponse.status === 200) { const toCache = networkResponse.clone(); // ← 必须在这里 clone caches.open(CURRENT_CACHE_NAME).then(cache => cache.put(event.request, toCache)); } return networkResponse; // ← 原始 response 还可用 })
容易踩的坑: 只在
cache.put()
里 clone,但忘了
return
时用原始对象 对非 200 响应(如 404、500)也尝试 clone 并缓存——这类响应通常不该进缓存,且部分浏览器不支持缓存 error response 在
install
阶段用
cache.addAll()
时,传入的 URL 列表里包含重定向响应(302)——
addAll
会失败,需先 fetch 再 put 缓存优先不是“设个开关就完事”,它依赖 install 预置、fetch 显式匹配、activate 清理、response 正确复用这四个环节严丝合缝。少一个,要么不生效,要么存一堆垃圾,要么某天突然返回错数据。

相关文章