application cache已彻底失效,chrome 95+、firefox 85+、safari 16.4+全面移除支持;manifest属性无效,唯一可行离线方案是service worker + cache api,须https(或localhost)部署并正确注册验证。

Application Cache 已彻底失效,Chrome 95+、Firefox 85+、Safari 16.4+ 全面移除支持。你加了 manifest="app.appcache" 或配了 MIME 类型,页面依然空白或报错,不是配置漏了,是浏览器根本不再认它。
Service Worker 注册失败的常见原因
注册脚本没跑起来,就别谈缓存了。最常卡在这几步:
-
navigator.serviceWorker是undefined→ 页面没走 HTTPS(或非localhost),浏览器直接禁用 API -
sw.js返回 404 / 302 / 500 → 路径写错,或服务器返回了重定向、错误状态码 -
sw.js响应头含Cache-Control: no-store或no-cache→ 浏览器拒绝注册(Nginx/Apache 默认可能加了这类头) - 同域名已有激活中的 Service Worker → 新脚本注册后卡在
waiting状态,不生效(需调用skipWaiting()或手动unregister())
验证方式:打开 DevTools → Application → Service Workers,看是否显示 “Active”;若为空白或报错,说明注册根本没成功。
install 阶段缓存资源全部失败的典型表现
cache.addAll() 是原子操作:列表里任一 URL fetch 失败(404、跨域、MIME 不匹配、响应头禁止缓存),整个缓存中止,Worker 卡在 installing 状态,后续 fetch 事件也不会触发。
- 写了
['/', '/index.html'],但服务端对/返回的是 SSR 动态页,且带Cache-Control: no-store→ 缓存直接失败 -
sw.js在/js/sw.js,却写./style.css→ 解析成/js/./style.css,404 - 清单里写
/images/logo.png,实际文件是logo@2x.png或大小写不符(Linux 服务器区分大小写)→ 404
建议做法:所有路径用绝对路径(以 / 开头);install 前加 console.log('caching:', urlsToCache);对关键 URL 手动 fetch(url).then(r => r.ok ? r : Promise.reject(r)) 校验。
fetch 事件里只写 caches.match(event.request).then(r => r || fetch(event.request)) 为什么不行
这是“假离线”——HTML 能加载,但 JS/CSS/图片/接口全崩。因为:
-
caches.match()只查 Cache API 缓存,不查 HTTP 缓存;没预缓存的资源(比如 API 接口)必然 miss,直接 fallback 到fetch(),断网时就net::ERR_FAILED - 没区分请求类型:
event.request.destination === 'document'的 HTML 请求该优先缓存兜底;destination === 'script'或'style'的静态资源必须提前缓存好;而destination === 'json'的 API 请求不该缓存旧数据,应明确走网络或返回自定义错误页
正确分发逻辑示例:
self.addEventListener('fetch', event => {
const { request } = event;
const dest = request.destination;
if (dest === 'document') {
event.respondWith(
caches.match(request).then(r => r || caches.match('/offline.html'))
);
} else if (['script', 'style', 'image', 'font'].includes(dest)) {
event.respondWith(
caches.match(request).then(r => r || fetch(request))
);
} else if (dest === 'json') {
event.respondWith(
fetch(request).catch(() => new Response(JSON.stringify({ error: 'offline' }), {
headers: { 'Content-Type': 'application/json' }
}))
);
}
});
file:// 协议下能用 Service Worker 吗
不能。navigator.serviceWorker 在 file:// 协议下始终为 undefined,这是浏览器强制限制。想本地双击运行又离线可用,唯一办法是:
- 静态资源全内联(
<script></script>、<style></style>、Base64 图片) - 用
localStorage或IndexedDB存用户数据,不依赖网络 - 放弃 Service Worker,接受“无网络即无动态行为”的事实
真正可靠的离线体验,必须部署在 HTTPS 或 localhost 上——这不是开发便利性问题,是浏览器安全模型的硬性边界。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











