学习目标

  • 理解Application Cache的核心作用及工作原理
  • 掌握缓存清单(manifest文件)的创建与配置方法
  • 实现基础的离线资源缓存与更新策略
  • 了解Application Cache的兼容性问题及替代方案

概念讲解

离线缓存(Application Cache) 是HTML5提供的一种本地缓存机制,允许Web应用将关键资源(HTML/CSS/JS/图片等)存储在客户端,使得应用在无网络连接时仍能正常访问。其核心优势在于:

  • 离线可用性:用户首次访问后,即使断网也能加载缓存内容
  • 提升加载速度:缓存资源直接从本地读取,减少网络请求
  • 减少服务器负担:重复资源无需重复下载

工作原理

  1. 通过页面<html>标签的manifest属性指定缓存清单文件
  2. 浏览器首次加载时解析manifest文件,下载并缓存指定资源
  3. 后续访问时优先从缓存加载资源,同时检查manifest文件是否更新
  4. 若manifest文件有变化,重新下载所有指定资源并更新缓存

语法参考

1. 缓存清单文件(.appcache)结构

缓存清单文件是一个纯文本文件,以.appcache为扩展名,包含三部分指令:

指令区域 作用描述 示例语法
CACHE MANIFEST 声明文件为缓存清单(必须放在第一行) CACHE MANIFEST
CACHE: 指定需要缓存的资源(默认区域,可省略指令名) CACHE:\n/index.html\n/style.css
NETWORK: 指定必须联网才能访问的资源(不缓存) NETWORK:\n/api/*\nhttps://*
FALLBACK: 指定资源访问失败时的替代方案(离线时生效) FALLBACK:\n/offline.html

2. HTML页面引用

<html>标签中添加manifest属性指向缓存清单文件:

<!DOCTYPE html>
<html lang="zh-CN" manifest="app.appcache">
<head>
  <meta charset="UTF-8">
  <title>离线应用示例</title>
</head>
<body>
  <!-- 页面内容 -->
</body>
</html>

3. 核心API

通过applicationCache对象监听缓存状态变化:

事件/方法 描述
update() 手动检查缓存更新
swapCache() 切换到新缓存(需在updateready事件中调用)
status 返回当前缓存状态(0:未缓存,1:闲置,2:检查中,3:下载中,4:更新就绪)
onupdateready 缓存更新完成时触发
onerror 缓存过程出错时触发

实战示例

示例1:基础缓存清单配置

1. 创建缓存清单文件app.appcache

CACHE MANIFEST
# 版本号:v1.0.0(修改此值触发缓存更新)

# 需缓存的核心资源
CACHE:
/index.html
/css/style.css
/js/app.js
/images/logo.png

# 必须联网访问的资源
NETWORK:
/api/data
https://fonts.googleapis.com

# 离线时的替代页面
FALLBACK:
/ /offline.html

2. 页面引用与缓存控制

<!DOCTYPE html>
<html lang="zh-CN" manifest="app.appcache">
<head>
  <meta charset="UTF-8">
  <title>离线应用Demo</title>
  <link rel="stylesheet" href="/css/style.css">
</head>
<body>
  <h1>我的离线应用</h1>
  <img src="/images/logo.png" alt="Logo">
  <script src="/js/app.js"></script>
  <script>
    // 监听缓存更新事件
    window.applicationCache.addEventListener('updateready', function() {
      if (window.applicationCache.status === window.applicationCache.UPDATEREADY) {
        // 提示用户刷新页面
        if (confirm('应用有更新,是否立即刷新?')) {
          window.applicationCache.swapCache(); // 切换到新缓存
          window.location.reload(); // 刷新页面
        }
      }
    }, false);

    // 手动检查更新
    function checkUpdate() {
      window.applicationCache.update();
    }
  </script>
  <button onclick="checkUpdate()">检查更新</button>
</body>
</html>

示例2:离线替代页面实现

当用户请求的资源无法访问(离线状态)时,通过FALLBACK指令返回替代页面:

# app.appcache 中添加
FALLBACK:
/news /offline-news.html
/images /images/offline-placeholder.png
  • /news页面无法访问时,返回/offline-news.html
  • 当任何图片无法加载时,显示占位图

注意事项

1. 缓存更新机制

  • manifest文件修改触发更新:浏览器通过比对manifest文件的内容(而非文件名)判断是否需要更新,建议在文件中添加版本号注释(如# v1.0.1),修改版本号即可触发全量更新
  • 更新时机:仅在页面加载时检查更新,若需实时检查,需手动调用applicationCache.update()

2. 兼容性问题

  • 支持情况:IE10+部分支持,Chrome/Firefox/Safari完全支持,但Chrome 85+已废弃,推荐使用Service Worker替代
  • 替代方案:现代Web应用建议使用Service Worker + Cache API,提供更灵活的缓存控制和更新策略

3. 常见错误排查

  • 跨域问题:manifest文件必须与页面同源,不支持跨域引用
  • MIME类型:服务器需正确设置manifest文件的MIME类型为text/cache-manifest(Nginx/Apache需配置)
  • 缓存大小限制:不同浏览器对离线缓存的容量限制不同(通常5MB~50MB),超出会导致缓存失败

自测题

  1. Application Cache的三个核心指令是什么?分别作用是什么?
  2. 如何触发Application Cache的资源更新?
  3. 当用户处于离线状态时,访问已缓存的资源和未缓存的资源会有什么不同表现?
  4. Application Cache与Service Worker相比,主要局限性是什么?