1. Application Cache 简介
1.1. 什么是 Application Cache
HTML5 引入了应用程序缓存,这意味着 web 应用可进行缓存,并可在没有因特网连接时进行访问。
应用程序缓存为应用带来三个优势:
- 离线浏览 - 用户可在应用离线时使用它们
- 速度 - 已缓存资源加载得更快
- 减少服务器负载 - 浏览器将只从服务器下载更新过或更改过的资源
1.2. 应用缓存原理
HTML5 的离线存储是基于一个 manifest 文件(缓存清单文件,后缀为 .appcache)的缓存机制(不是存储技术),通过这个文件上的清单解析离线存储资源,这些资源就会像 cookie 一样被存储了下来。之后当网络在处于离线状态时,浏览器会通过被离线存储的数据进行页面展示。
1.3. 使用方法
- manifest 文件的建议的文件扩展名是:.appcache
- 首先在文档的 html 标签中设置 manifest 属性,引用 manifest 文件
- 然后配置 manifest 文件,在 manifest 文件中编写离线存储的资源
- 此外,必须要在服务器端正确的配置 MIME-type。即 text/cache-manifest
1.4. 浏览器兼容性
Offline Web Applications 浏览器兼容性
2. Manifest 文件
manifest 文件是简单的文本文件,它告知浏览器被缓存的内容(以及不缓存的内容)。
manifest 文件可分为三个部分:
- CACHE MANIFEST - 在此标题下列出的文件将在首次下载后进行缓存
- NETWORK - 在此标题下列出的文件需要与服务器的连接,且不会被缓存
- FALLBACK - 在此标题下列出的文件规定当页面无法访问时的回退页面(比如 404 页面)
3. 简单实例
接下来,用具体实例来看一下如何使用离线缓存。
文件夹目录如下:
cache.html 代码如下:1
2
3
4
5
6
7
8
9
10
11
12
<html manifest="cache.appcache">
<head>
<meta charset="UTF-8">
<title>应用缓存</title>
<link rel="stylesheet" href="cache.css">
<script src="cache.js"></script>
</head>
<body>
<img src="cache.png" alt="cache.png">
</body>
</html>
cache.appcache 代码如下:1
2
3
4
5
6
7
8
9CACHE MANIFEST
# v0.0.1
CACHE:
/cache.css
/cache.js
/cache.png
NETWORK:
*
manifest 属性可指向绝对网址或相对路径,但绝对网址必须与相应的网络应用同源。manifest 除了缓存 manifest.appcache 文件所指定的资源外,还必定会缓存当前的 html 页面。可以使用星号来指示所有其他资源/文件都需要因特网连接。
注意:这里的版本号,是我们人为规定的,而非是 manifest 自带的属性,当每一次 html 加载到 manifest 时,会对 manifest 配置文件进行脏检查,当检测到 manifest 文件被修改后,之前的缓存将会被弃用,转而去根据 manifest 文件中配置的新内容进行缓存。
缓存查看
使用 node 或其他方法启动服务后,访问页面之后尝试关闭网络环境,依然能够访问。
4. window.applicationCache
window.applicationCache 对象是对浏览器的应用缓存的编程访问方式。其 status 属性可用于查看缓存的当前状态。
4.1. status 属性值
属性值 | 含义 | 描述 |
---|---|---|
0 | UNCACHED |
无缓存, 即没有与页面相关的应用缓存 |
1 | IDLE |
闲置,即应用缓存未得到更新 |
2 | CHECKING |
检查中,即正在下载描述文件并检查更新 |
3 | DOWNLOADING |
下载中,即应用缓存正在下载描述文件中指定的资源 |
4 | UPDATEREADY |
更新完成,所有资源都已下载完毕 |
5 | IDLE |
废弃,即应用缓存的描述文件已经不存在了,因此页面无法再访问应用缓存 |
以下代码使用 status 属性为当前通过网页所加载的文档确定应用程序缓存的状态
1 | var oAppCache = window.applicationCache; |
4.2 APPCACHE 事件
浏览器会对下载进度、应用缓存更新和错误状态等情况触发相应事件。
事件 | 描述 |
---|---|
checking |
每当应用程序载入的时候,都会检查该清单文件,也总会首先触发checking 事件。 |
noupdate |
如果没有改动,同时应用程序也已经缓存了noupdate 事件被触发,整个过程结束。 |
downloading |
如果还未缓存应用程序,或者清单文件有改动,那么浏览器会下载并缓存清单中的所有资源 ,触发downloading 事件,同时意味着下载过程开始。 |
progress |
在下载过程中会间断性触发progress 事件,通常是在每个文件下载完毕的时候。 |
cached |
下载完成并且首次将应用程序下载到缓存中时,浏览器会触发cached 事件。 |
updateready |
当下载完成并将缓存中的应用程序更新后,浏览器会触发updaterady 事件。 |
error |
如果浏览器处于离线状态,检查清单列表失败,则会触发error 事件,当一个未缓存的应用程序引用一个不存在的清单文件,也会触发此事件。 |
obsolete |
如果一个缓存的应用程序引用一个不存在的清单文件,会触发obsolete ,同时将应用从缓存中移除之后不会从缓存而是通过网络加载资。 |
以下代码段为每种缓存事件类型设置了事件监听器:
1 | function handleCacheEvent(e) { |
5. 更新缓存
一旦应用被缓存,它就会保持缓存直到发生下列情况:
- 用户清空浏览器缓存
- manifest 文件被修改
- 由程序来更新应用缓存
以 “#” 开头的是注释行,但也可满足其他用途。应用的缓存会在其 manifest 文件更改时被更新。如果您编辑了一幅图片,或者修改了一个 JavaScript 函数,这些改变都不会被重新缓存。更新注释行中的日期和版本号是一种使浏览器重新缓存文件的办法。
由程序来更新应用缓存:
1 | oAppCache.addEventListener('updateready', function(){ |
6. 注意事项
- 更新清单中列出的某个文件并不意味着浏览器会重新缓存该资源,清单文件本身必须进行更改。
- 浏览器对缓存数据的容量限制可能不太一样(某些浏览器设置的限制是每个站点 5MB)。
- 如果manifest文件,或者内部列举的某一个文件不能正常下载,整个更新过程都将失败,浏览器继续全部使用老的缓存。
- 引用 manifest 的 html 必须与 manifest 文件同源,在同一个域下。FALLBACK 中的资源必须和 manifest 文件同源。
- 浏览器会自动缓存引用 manifest 文件的 HTML 文件,这就导致如果改了 HTML 内容,也需要更新 manifest 文件版本或者由程序来更新应用缓存才能做到更新。
- 若遇到如此报错 “Application Cache Error event: Manifest fetch failed (404)” ,其原因是 manifest 文件需要正确的配置 MIME-type(描述该消息的媒体类型),即 “text/cache-manifest” ,必须在服务器端进行配置。不同服务器配置方式不一样。
在tomcat服务器中的conf/web.xml中添加:
1 | <mime-mapping> |
7. 与传统浏览器缓存区别
- 离线缓存是针对整个应用,浏览器缓存是单个文件。
- 离线缓存断网了还是可以打开页面,浏览器缓存不行。
- 离线缓存可以主动通知浏览器更新资源。