manifest让网页实现离线访问

警告:对于产生动态内容的博客等页面,请勿轻易尝试该特性,除非你使用了AJAX等异步加载方式(依然不建议)。

以前,网页和APP相比的主要缺点,一个是性能,另一个就是网络依赖。现在随着HTML5的发展,网页已经可以实现在无网络的情况下,离线访问了。比如outlook.com就可以设置脱机访问,即使电脑没联网,你也能打开该网页,查阅邮件甚至撰写草稿。虽然平时大多用邮件客户端,但偶尔打开outlook网页,就会从我那使用了多年的网址导航点进去,所以也就为它开启了离线访问功能。感兴趣的可以用新版浏览器打开qifu.me/links/或者qifu.me/hello/,待浏览器缓存一会儿,然后断开网络试一下。

实现这一功能的特性就是manifest,下面直接说怎么实现。

首先,在页面的<html>元素里添加manifest,这样就可以告诉浏览器页面开启了应用缓存,并在这个清单文件里面列出需要缓存的资源。比如:

<html lang="zh" manifest="manifest.appcache">

注意,这个文件的地址必须和页面同源,而且文件的MIME类型必须为“text/cache-manifest”,可以通过修改服务器的“mime.types”或“.htaccess”等方法为相应后缀添加这个类型,当然你也可以使用其它文件名和后缀,比如qifu.manifest。

这个清单文件里面的缓存指令共分三类,每段以 “CACHE:” 、 “FALLBACK:” 或 “NETWORK:” 开始,然后换行,列出一行行的记录,三类指令不分先后,且可以多段穿插。CACHE告诉浏览器哪些资源要缓存;FALLBACK告诉浏览器如果某资源无法获取时,用哪个资源替代;NETWORK则指明了哪些资源强制必须联网。比如:

CACHE MANIFEST
#version 1.0
CACHE:
https://qifu.me/style.css?version=1.0
https://qifu.me/script.js?version=1.0

FALLBACK:
/online.php /offline.php
NETWORK:
*

引用了这个manifest清单文件的页面会自动被缓存,无需声明,你也无法禁止它被缓存。不引用manifest的页面,是不能调用任何离线缓存资源的。

第一行是固定格式,第二行的注释是版本号,因为缓存建立后,下次浏览器就不再访问被缓存的资源(包括这个页面本身),只检查这个清单文件是否有更改,更改了就重新缓存一遍,但是只有下次访问才可以看到缓存的新内容,除非你使用js判断是否有更新,然后自动刷新该页面:

// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
  window.applicationCache.addEventListener('updateready', function(e) {
    if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
      // Browser downloaded a new app cache.
      // Swap it in and reload the page to get the new hotness.
      window.applicationCache.swapCache();
      window.location.reload();
    }
  }, false);
}, false);

一旦被缓存,你就不能通过改变参数里的版本号来强制浏览器刷新某个资源的缓存了,因为你改的版本号浏览器看不到,它直接用缓存的旧html页面,但是考虑到有些低版本浏览器不支持这一特性,还是建议保留问号后面的version。而且被缓存的资源,浏览器就不再遵守http header里面的缓存时间,直到清单文件更新缓存。

FALLBACK段落的每条记录分两部分,空格前面是原始资源,正常情况下浏览器访问的就是这个,后面那个是后备资源,当尝试请求资源失败时会使用它代替前面那个。这个后备资源浏览器会自动缓存,不需要你另外指明或者在html页面引用。同样,CACHE后面也可以列出正常情况下用不到的资源,以防后备资源需要调用。

NETWORK段落的星号是个通配符,表示其余资源全部绕过缓存,必须每次联网访问,当然也可以指定具体的地址。但是CACHE段落里面是不允许使用通配符的。

就这么简单:一条引用、一个清单文件,页面已经可以脱机访问了。亲测Edge、IE、Chrome等新版浏览器均支持。看完你也就明白为什么不要轻易为博客等动态页面使用该特性了,因为缓存太强……

随便看看

本文共有39条评论

  1. 其实任何页面都可以缓存,曾经老猫拨号上网,网速甚至不到512K/秒的时候,浏览器就有脱机浏览的功能了。那时候老师还教过我们如何缓存多层网页。不过现在大概没什么人知道这个功能了吧。

    1. 这个功能以前也用过,不过需要用户手动设置;而manifest作为一个标准,脱机缓存是在用户打开网页后自动完成,无需任何额外操作。

        1. 离线的主要目的还是脱机可用,比如我的网址导航,如果断网后打开浏览器空白,就不能点击跳转到其它脱机可用的网站了。
          当然,也可以起到强缓存省资源的作用。

    1. 怎样都行,重点是只要整个文件有变化就会更新缓存,即使不改版本号,加个空格、换行都一样的效果。

您好,#请填信息#填写

发表评论