HTML 的离线存储怎么使用?原理

在用户没有与因特网连接时,可以正常访问站点或应用,在用户与因特网连接时,更新用户机器上的缓存文件。

原理:HTML5 的离线存储是基于一个新建的 .appcache 文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像 cookie 一样被存储了下来。之后当网络在处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示。

使用方法

只要在头部加一个 manifest 属性就 ok 了:

<!DOCTYPE html>
<html manifest="cache.manifest">
...
</html>

然后 cache.manifest 文件的书写方式如下:

CACHE MANIFEST
#v0.11

CACHE:
js/app.js
css/style.css

NETWORK:
resourse/logo.png

FALLBACK:
/ /offline.html

解析

离线存储的 manifest 一般由三个部分组成:

  1. CACHE:需要离线缓存的资源列表
  2. NETWORK:只有联网时才能访问的资源(白名单)
  3. FALLBACK:离线时的替代资源映射

浏览器是怎么对 HTML5 的离线储存资源进行管理和加载的呢

在线的情况下,浏览器发现 html 头部有 manifest 属性,它会请求 manifest 文件,如果是第一次访问 app,那么浏览器就会根据 manifest 文件的内容下载相应的资源并且进行离线存储。

如果已经访问过 app 并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的 manifest 文件与旧的 manifest 文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会重新下载文件中的资源并进行离线存储。离线的情况下,浏览器就直接使用离线存储的资源。

补充

补充:Application Cache(appcache)曾被广泛使用,但因为设计复杂、坑多,已经被 Service Worker + Cache API 完全取代。

Application Cache 的坑

  • manifest 一旦写错,整个页面所有 CACHE 资源都会失效
  • manifest 本身也会被强缓存,更新困难
  • 只要列表里任何资源 404 都会导致整个缓存失败
  • 没有细粒度控制,只能"全部替换"

现代替代:Service Worker

// 注册 Service Worker
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js');
}
// sw.js
self.addEventListener('install', (e) => {
  e.waitUntil(
    caches.open('v1').then((cache) =>
      cache.addAll(['/', '/index.css', '/app.js'])
    )
  );
});

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

来源整理自:我的有道云笔记