HTML5 离线缓存(Application Cache)完全指南
Introduction
你有没有遇到过这种情况:正在阅读一篇技术文章,突然网络断了,页面直接报错打不开?Application Cache(AppCache)就是解决这个问题的标准方案。它允许浏览器缓存整个页面及相关资源(CSS、JS、图片),让网站在离线状态下依然可用。
本指南覆盖:manifest 文件写法、引用方式、升级机制、以及 2020 年后浏览器废弃 AppCache 的历史背景和现代替代方案。
---
基础语法
1. 创建 manifest 文件
manifest 文件扩展名通常为 .appcache,必须在服务器上由 Web 服务器提供正确的 MIME 类型(text/cache-manifest)。
示例:xianheng.appcache(放在网站根目录)
CACHE MANIFEST
版本号:每次更新内容后必须改这个,否则浏览器不会刷新缓存
2024-01-15 v1.0.0
CACHE:
/index.html
/styles.css
/app.js
/images/logo.png
NETWORK:
这些资源永远不走缓存,每次联网获取
*
FALLBACK:
当无法联网时,用 /offline.html 替代所有页面
/ /offline.html
2. 在 HTML 中引用 manifest
在 标签加入 manifest="/xianheng.appcache" 属性:
欢迎访问绍大技术网
manifest 文件三大部分
| 区域 | 作用 | 示例 |
|------|------|------|
| CACHE: | 明确缓存的文件 | /images/logo.png |
| NETWORK: | 永远联网获取的资源 | * 或 /api/* |
| FALLBACK: | 联网失败时的替代页面 | / /offline.html |
3. JavaScript 检测与应用
if ('applicationCache' in window) {
const appCache = window.applicationCache;
appCache.addEventListener('checking', () => { console.log('检查更新...'); });
appCache.addEventListener('updateready', () => {
console.log('新版本已缓存,准备更新!');
if (confirm('有新版本可用,是否立即更新?')) {
appCache.swapCache();
location.reload();
}
});
appCache.addEventListener('error', (e) => { console.error('AppCache 出错:', e); });
appCache.update();
}
---
运行效果
1. 首次访问:浏览器下载 manifest 中列出的所有文件,存到本地缓存
2. 再次访问:直接加载本地缓存,页面秒开,无需联网
3. manifest 更新时:浏览器自动后台下载新文件,但不会立即替换——等 swapCache() 或页面刷新后才启用新缓存
4. 断网测试:访问过的页面仍可正常浏览,NETWORK 列表的资源会加载失败,FALLBACK 指定的页面自动展示
---
常见问题与注意事项
Q1: manifest 更新了但浏览器没反应?
AppCache 只在 manifest 文件内容发生变化时才触发更新。每次更新内容后,务必同时修改 manifest 顶部的版本号注释。Q2: 服务器更新后用户看到旧版?
在 updateready 事件里主动调用 swapCache() + location.reload()。Q3: 浏览器报 AppCache 错误?
1. 确认服务器为 .appcache 文件返回了正确的 MIME 类型 text/cache-manifest 2. manifest 文件本身必须在 CACHE 列表中 3. 所有相对路径文件存在且可访问Nginx 配置:
location ~ .appcache$ {
add_header Content-Type text/cache-manifest;
expires 0;
}
Q4: AppCache 已废弃,现在用什么?
2020年起,所有主流浏览器不再支持 AppCache,推荐使用 Service Worker + Cache API:const CACHE_NAME = 'v1';
const urlsToCache = ['/', '/styles.css', '/app.js'];
self.addEventListener('install', (e) => {
e.waitUntil(caches.open(CACHE_NAME).then(cache => cache.addAll(urlsToCache)));
});
self.addEventListener('fetch', (e) => {
e.respondWith(caches.match(e.request).then(r => r || fetch(e.request)));
});
---
延伸阅读
- HTTP 缓存机制详解 - Cache-Control / ETag / Last-Modified 对比
- PWA 渐进式应用开发实战 - 完整的 PWA 构建指南(待发布)
- HTML5 离线缓存 - Service Worker 进阶用法(待发布)
---
欢迎补充指正!如有具体使用场景的问题,欢迎在评论区交流。