HTML5离线缓存是什么_HTML5离线应用实现原理与使用指南【详解】

2次阅读

html5离线缓存需显式声明manifest文件,满足存在性、内容变更及资源可下载三条件,否则静默失败;已由service worker取代,现代项目应迁移。

HTML5离线缓存是什么_HTML5离线应用实现原理与使用指南【详解】

离线缓存不是“自动变离线”,而是靠 manifest 文件触发的显式声明

html5 的离线缓存(Application Cache)本质是一套**浏览器强制执行的静态资源预加载机制**,不是你加个 manifest 属性就“顺带”缓存了——它必须满足三个硬条件:文件存在、内容变化、且所有声明资源可完整下载。一旦任一资源 404 或跨域,整个缓存过程静默失败,浏览器继续用旧缓存甚至直接报错。

  • manifest 文件第一行必须是 CACHE MANIFEST,大小写敏感,不能有 bom
  • HTML 文件与 manifest 文件必须同源(协议+域名+端口完全一致)
  • CACHE: 列出的资源,哪怕只是 HTML 自身,也必须能被浏览器 GET 成功;否则缓存不会建立
  • 浏览器只在 manifest 文件内容字节级变化时才触发更新,改注释、加空格都算;但改资源文件本身不触发更新

service worker 已取代 Application Cache,但老项目还在用,得知道怎么救

chrome 94+、firefox 84+ 已彻底移除 applicationCache API,safariios 16.4 起也标记为废弃。你现在看到的“离线能用”,大概率是 service worker 在兜底,或者用户设备还跑着旧版浏览器。如果维护老项目,别碰 window.applicationCache.update() —— 它在新浏览器里是 undefined,调用直接报错。

  • 检查是否启用:if ('applicationCache' in window),而不是 if (window.applicationCache)
  • 监听事件要用 window.applicationCache.addEventListener('updateready', ...),但注意该事件只在新缓存就绪后触发一次,且需手动 swapCache()
  • 真正可靠的 fallback 是提前注册一个最小 service worker,哪怕只拦截 /index.html 并返回 cache.match(),也能绕过 AppCache 失效风险

manifest 文件写错一行,整个离线逻辑就瘫痪

Manifest 看似简单,但格式容错率极低。常见失效场景不是代码写错,而是部署或路径细节翻车:

  • NETWORK: 下写 * 是合法的,但 Safari 对通配符支持不稳定,建议明确列出如 /api/ /upload
  • FALLBACK: 后面两个路径必须同源,且第二个(离线页)必须在 CACHE: 里声明过,否则离线时 404
  • 相对路径以 manifest 文件所在目录为基准,不是 HTML 所在目录;比如 manifest="v2/cache.manifest",那里面写的 style.css 就是相对于 /v2/
  • 服务器必须返回 text/cache-manifest MIME 类型,nginx 需加 add_header Content-Type "text/cache-manifest";

离线包 ≠ 离线应用,真要可靠得自己管资源生命周期

Application Cache 是“全有或全无”的粗粒度缓存,没版本灰度、没增量 diff、没校验哈希——它只认 manifest 内容变了没。现代 H5 离线包(如电商首页、活动页)基本都用 ServiceWorker + IndexedDB + zip 解包 自研方案,manifest 只剩历史包袱。

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

  • 想做热更新?AppCache 做不到,每次更新都是全量覆盖,用户得等全部资源下完才能切新包
  • 想校验完整性?AppCache 没 hash 字段,篡改一个 js 文件,浏览器照常执行
  • 想控制缓存空间?AppCache 由浏览器统一管理,android webview 甚至可能因满 5MB 强制清空
  • 真正可控的做法:用 fetch() 下载 zip 包 → JSZip 解压 → 存进 IndexedDB → SW 拦截请求时查 DB 返回 blob URL

AppCache 的设计初衷是“让简单站点快速离线”,但它对工程化、稳定性、调试性的支持几乎为零。现在还依赖它,等于把缓存逻辑交给了浏览器黑盒——而黑盒,往往只在出问题时才打开。

text=ZqhQzanResources