manifest attribute离线缓存替代方案_service worker使用指南【指南】
manifest 属性已废弃,Service Worker 是唯一可行的离线缓存方案

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
先说一个核心结论:想在 Web 上实现稳定可靠的离线体验,老路已经彻底行不通了。
manifest attribute 已被弃用,别再配 manifest 属性了
一个时代结束了。从 Chrome 94 版本开始,对 HTML 标签里的 manifest 属性的支持被完全移除。其实 Firefox 和 Safari 浏览器更早就放弃了它。这意味着,即使你还在代码里兢兢业业地写着 ,浏览器也只会默默忽略它——不报错,但缓存功能完全失效。这事儿不是开发者用法的问题,而是这个机制自诞生起就伴随着兼容性差、更新策略过于僵硬、无法进行细粒度控制等硬伤,最终被标准层面正式废弃。
Service Worker 是唯一可行的离线缓存替代方案
那么,路在何方?答案是明确的,且只有一条:Service Worker。它不是什么“备选方案”,而是当前 Web 平台唯一能够真正接管网络请求、实现自定义离线缓存逻辑的核心机制。这里有几个关键点必须抓住:
- 首先,它必须通过 Ja vaScript 动态注册,并且只在 HTTPS 环境(或者本地
localhost)下才能生效。 na vigator.serviceWorker.register()这行代码的调用时机很有讲究。建议放在页面加载的早期,比如在底部的里就执行。如果注册得太晚,首屏的关键资源可能就拦不住了。- 注册时指向的脚本文件(比如
sw.js)要特别注意:别给它加查询参数(像sw.js?v=1这样),浏览器会把它当成一个全新的脚本,容易导致重复注册或者更新失败。 - 首次注册成功后,Service Worker 就有了自己的“生命周期”,它独立于页面。即使你关闭了浏览器标签页,它也可能在后台运行;而当你刷新页面时,控制页面的可能还是旧版本,这时候就需要手动触发
skipWaiting()来让新版立即上岗。
缓存策略要按资源类型拆开写,别一股脑 cache.addAll()
实现离线功能,最难也最重要的一环是缓存策略。切忌对所有资源“一视同仁”,用同一个 cache.addAll() 打包处理。不同资源,策略应该截然不同:
- 静态资源:比如 JS、CSS、字体、图片,它们通常版本化明确,适合采用“缓存优先”策略。
- HTML 文档:内容可能频繁更新,建议采用“网络优先,失败回退”的策略,确保用户第一时间看到最新内容,断网时才展示缓存版本。
- API 接口:动态数据通常不应该直接塞进 Cache Storage。更合理的做法是让它走网络,并通过 HTTP 标准的
Cache-Control头部来控制缓存。
具体怎么实现?看看下面这个按资源类型分流的 fetch 事件处理示例:
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.origin === location.origin) {
if (url.pathname.endsWith('.html')) {
// HTML:先试网络,断网时返回缓存的 fallback 页面
event.respondWith(
fetch(event.request).catch(() => caches.match('/offline.html'))
);
} else if (/\.(js|css|png|jpg|woff2)$/.test(url.pathname)) {
// 静态资源:缓存优先,后台静默更新
event.respondWith(caches.match(event.request).then(r => r || fetch(event.request)));
event.waitUntil(updateStaticCache()); // 单独函数更新缓存
}
}
});
调试 Service Worker 极容易掉坑,重点盯这三个地方
开发 Service Worker 的过程,几乎就是和调试工具斗智斗勇的过程。经验表明,以下几个地方是高频“雷区”,需要重点盯防:
- 工具选择:Chrome DevTools 里的
Application > Service Workers面板是你的主战场,信息最可靠。千万别只依赖页面的 console.log,因为 Service Worker 的日志默认是独立的,需要手动切换到对应的 Service Worker 上下文才能看到。 - 注册失败:如果看到控制台报
Failed to register a ServiceWorker,先检查两个点:一是sw.js文件是否能正常访问(404?),二是服务器返回的 MIME 类型是否正确(必须是text/ja vascript)。 - 更新不生效:在 Service Workers 面板里,如果新版本的状态显示为 “waiting”,那就说明它卡住了。你需要在新脚本里调用
self.skipWaiting(),并在页面中监听controllerchange事件来触发页面刷新或重载。 - 缓存未命中:有时候你觉得该命中的缓存却没命中。这时可以在 Console 里手动运行
caches.open('my-cache').then(cache => cache.keys()),查看缓存里到底存了些什么键。需要警惕的是,URL 末尾一个斜杠、大小写字母、查询参数的细微差异,都可能导致完全匹配不上。
归根结底,缓存匹配的精度要求极高。别想当然地认为“路径看起来一样就行”,细节决定成败。
相关攻略
manifest 属性已废弃,Service Worker 是唯一可行的离线缓存方案 先说一个核心结论:想在 Web 上实现稳定可靠的离线体验,老路已经彻底行不通了。 manifest attribute 已被弃用,别再配 manifest 属性了 一个时代结束了。从 Chrome 94 版本开始,
HTML table 的 frame 属性详解:它究竟控制什么? 在 HTML 表格开发中,frame 属性常常让开发者感到疑惑。作为 标签的一个原生属性,它的功能其实非常具体且有限:它专门负责控制表格最外围边框的显示与隐藏,即决定上、下、左、右四条外边线中哪些需要绘制出来。需要注意的是,边框的颜色
accept属性仅影响浏览器文件选择过滤,不校验文件类型;正确写法需同时提供MIME类型和扩展名,如 "application vnd openxmlformats-officedocument spreadsheetml sheet, xlsx ",且后端必须校验文件头和真实类型。 先说一个核心结论:
name属性:表单数据的“身份证”与提交密码 当你精心设计了一个表单,满心期待用户提交数据,却发现后端收到的请求体空空如也——这种抓狂的经历,很多开发者都遇到过吧?问题的根源,往往就出在那个看似不起眼,实则至关重要的属性上:name。 name属性是表单数据提交的唯一键名 这里有个必须牢记的底层逻辑
role属性唯一作用是告知屏幕阅读器元素的语义角色,仅在原生HTML无法准确表达时才需使用;滥用、冗余或错误设置会破坏无障碍体验。 开发圈子里有种误解,以为role属性能“增强样式”或是“方便Ja vaScript查找元素”。其实不然,这个属性的使命非常纯粹:它仅仅是告诉屏幕阅读器——“这个元素在语
热门专题
热门推荐
一、财务系统更换:一场不容有失的“心脏手术” 如果把企业比作一个生命体,那么财务系统就是它的“心脏”。这颗“心脏”一旦老化,更换就成了必须面对的课题。但这绝非一次简单的软件升级,而是一场精密、复杂、牵一发而动全身的“外科手术”。数据显示,超过70%的ERP(企业资源计划)项目实施未能完全达到预期,问
在企业数字化转型的浪潮中,模拟人工点击软件:从效率工具到智能伙伴 企业数字化转型的路上,绕不开一个话题:如何把那些重复、枯燥的电脑操作交给机器?模拟人工点击软件,正是因此而成为了提升效率、降低成本的得力助手。那么,市面上的这类软件到底有哪些?答案其实很清晰。它们大致可以归为三类:基础按键脚本、传统R
一、核心结论:AI智能体是通往AGI的必经之路 时间来到2026年,AI智能体这个词儿,早就跳出了PPT和实验室的范畴。它不再是飘在天上的技术概念,而是实实在在地成了驱动全球数字化转型的引擎。和那些只能一问一答的传统对话式AI不同,如今的AI智能体(Agent)本事可大多了:它们能自己规划任务步骤、
一、核心结论:AI智能体交互的“桥梁”是行动层 在AI智能体的标准架构里,它与外部系统打交道,关键靠的是“行动层”。可以这么理解:感知层是Agent的五官,决策层是它的大脑,而行动层,就是那双真正去执行和操作的手。这一层专门负责把大脑产出的抽象指令,“翻译”成外部系统能懂的语言,无论是调用一个API
一、核心结论:AI人设是智能体的“灵魂” 在构建AI应用时,一个核心问题摆在我们面前:如何写好AI智能体的人设描述?这个问题的答案,直接决定了智能体输出的专业度与用户端的信任感。业界实践表明,一个优秀的人设描述,离不开一个叫做RBGT的模型框架,它涵盖了角色、背景、目标和语气四个黄金维度。有研究数据





