html5静态网页如何设置缓存_离线应用manifest用法【教程】

HTML5 manifest 已被所有主流浏览器彻底弃用,因其依赖存在严重缺陷的 AppCache 机制;W3C 标记为 obsolete,WHATWG 标准已删除;替代方案唯一可行的是 Service Worker + Cache API,需 HTTPS 环境、两次刷新生效,并精细管理缓存版本。

HTML5 的 manifest 已被现代浏览器彻底弃用,不能用于新项目。Chrome 从 94 版本起移除支持,Firefox 85+、Safari 早已禁用,所有主流浏览器均返回 DOMException: Failed to set the 'manifest' property on 'HTMLDocument' 或直接忽略

manifest 文件为什么完全失效了

它依赖过时的 AppCache 机制,存在严重设计缺陷:缓存更新不透明、资源失败导致整个缓存失效、无法按需更新单个文件、HTTPS 下行为不一致等。W3C 已将其标记为 obsolete,WHATWG HTML 标准中已删除该章节。

  • 访问含 manifest 属性的页面时,开发者工具 Network 面板不再显示 manifest 请求
  • navigator.onLinewindow.applicationCache 在新版本浏览器中为 undefined
  • 即使服务端返回正确的 text/cache-manifest MIME 类型,浏览器也完全不解析

替代方案:Service Worker + Cache API 是唯一可行路径

离线能力必须通过 Service Worker 实现,它支持精细控制缓存策略、版本化更新、后台同步等。

  • 必须在 HTTPS(或 localhost)环境*册,http:// 域名下会静默失败
  • 注册代码必须放在主页面的 JS 中,且不能在模块脚本(type="module")里直接调用 navigator.serviceWorker.register()
  • 首次注册后,页面需**刷新两次**才能生效:第一次注册 SW,第二次才由 SW 控制页面
if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js')
      .then(reg => console.log('SW registered: ', reg.scope))
      .catch(err => console.error('SW registration failed: ', err));
  });
}

静态网页最小可行离线缓存示例(sw.js)

以下 sw.js 仅缓存 HTML、CSS、JS、字体和图片,适用于纯静态站点,不处理动态请求或 API。

立即学习“前端免费学习笔记(深入)”;

  • 使用 cache.addAll() 预缓存关键资源,避免首次离线白屏
  • fetch 事件中优先匹配缓存,未命中再发网络请求(stale-while-revalidate 策略)
  • 每次更新 sw.js 文件内容(如改注释),浏览器才会触发新版本安装
const CACHE_NAME = 'static-v1';
const FILES_TO_CACHE = [
  '/',
  '/index.html',
  '/style.css',
  '/script.js',
  '/assets/logo.png'
];

self.addEventListener('install', (e) => {
  e.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => cache.addAll(FILES_TO_CACHE))
  );
});

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

真正棘手的是缓存版本管理与更新逻辑——比如如何让用户感知新版本可用、是否自动刷新页面、第三方资源(如 CDN 字体)能否缓存,这些细节没处理好,离线体验反而更差。