zoukankan      html  css  js  c++  java
  • HTML5离线存储 初探

    本文主要内容归纳如下:

    一、离线存储的作用;

    二、如何实现离线存储;

    三、applicationCache对象,及属性、事件、接口

    四、访问缓存应用,相应触发事件,及其对应状态;

    五、如何更新离线缓存

    六、demo演示:update后是否调用swapCache的区别;

    七、写在后面 

    一、离线存储的作用

    1、用户可离线访问你的应用,这对于无法随时保持联网状态的移动终端用户来说尤其重要

    2、用户访问本地的缓存文件,通常意味着更快的访问速度

    3、仅仅加载被修改过的资源,避免同一资源对服务器多次的请求,大大降低了对服务器的访问压力 

    二、如何实现离线存储

    1、在html标签里通过manifest属性引用一个cache.manifest文件,该文件里声明了浏览器需缓存的所有资源文件,如下所示: 

    <!DOCTYPE html>
    <html lang='cn' manifest='cache.manifest'>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>离线缓存示例页面</title>
    <!-- CSS文件引用 -->
    </head>
    
    <body>
    <!-- 各种标签 -->
    </body>
    
    <!-- 各种脚本文件  -->
    </html>

    2、关于cache.manifest的定义

    CACHE MANIFEST
    # 注释:需要缓存的文件,无论在线与否,均从缓存里读取
    chched.js
    cached.css
    
    # 注释:不缓存的文件,无论缓存中存在与否,均从新获取
    NETWORK:
    uncached.js
    uncached.css
    
    # 注释:获取不到资源时的备选路径,如index.html访问失败,则返回404页面
    FALLBACK:
    index.html 404.html

    3、几个需要关注的细节

    • cache.manifest 文件的MIME类型是text/cache-manifest,至于如何让web服务器返回.manifest文件时添加 Content-Type: text/cache-manifest,不同服务器配置细节不同,此处不展开
    • cache.manifest写法以CACHE MANIFEST开头,文件编码格式必须是utf-8
    • 引用cache.manifest的html文档会被默认包含进缓存清单

    4、归纳起来,步骤如下:

    • 配置服务器支持 cache.manifest 的Content-type: manifest
    • 编写 cache.manifest 文件
    • html页面引用cache.manifest文件

     

    三、applicationCache对象,及属性、事件、接口

    浏览器通过window.applicationCache对象来及其相应属性、接口、事件供用户构建离线应用,详细可见 applicationCache 

    //当前文档对应的applicationCache对象
    window.applicationCache
    
    //当前缓存所处的状态,为0~5的整数值,分别对应一个状态,并分别对应一个常量
    window.applicationCache.status
    
    window.applicationCache.UNCACHED === 0    //未缓存,比如一个页面没有制定缓存清单,其状态就是UNCACHED
    window.applicationCache.IDLE === 1 //空闲,缓存清单指定的文件已经全部被页面缓存,此时状态就是IDLE
    window.applicationCache.CHECKING === 2 //页面正在检查当前离线缓存是否需要更新
    window.applicationCache.DOWNLOADING === 3 //页面正在下载需要更新的缓存文件
    window.applicationCache.UPDATEREADY === 4  //页面缓存更新完毕
    window.applicationCache.OBSOLETE === 5  //缓存过期,比如页面检查缓存是否过期时,发现服务器上的.manifest文件被删掉了
    
    //常用API,在后面会稍详细介绍
    window.applicationCache.update()  //update方法调用时,页面会主动与服务器通信,检查页面当前的缓存是否为最新的,如不是,则下载更新后的资源
    window.applicationCache.swapCache()  //updateready后,更新到最新的应用缓存

    除了上面提及的属性、接口外,window.applicationCache还包含了一系列的事件,大部分与上面提到的 window.applicationCache.status对应,如下: 

    事件名 关联属性 事件释义
    onchecking CHECKING 见上文对关联属性的解释
    ondownloading DOWNLOADING -
    onupdateready UPDATEREADY -
    onobsolete OBSOLETE -
    oncached IDLE -
    onerror   更新出错,如检查更新时.manifest被人误删了
    onnoupdate   检查后,发现缓存无需更新
    onprogress   -

      

     

    四、访问缓存应用,相应触发事件,及其对应状态

    1、假设我们在第一次在chrome里面访问http://localhost/blog/html5/has_cache/cache.html,如下所示:

    打开控制台,看到如下:

    由上到下依次为(cache = window.applicationCache):

    1. 检查是否需要下载/更新缓存,cache.status===cache.CHECKING
    2. 发现本地还没有缓存文件,开始下载,cache.status===cache.DOWNLOADING
    3. 正在下载缓存文件,cache.staus===cache.PROGRESS
    4. 下载完毕,并缓存在本地,cache.status===cache.CACHED

    2、再次访问http://localhost/blog/html5/cache/has_cache/cache.html

    1)假设.manifest没有变化

    打开控制台,如下所示:

    由上到下依次为:

    1. 检查是否需要下载/更新缓存,cache.status===cache.CHECKING
    2. 发现服务器上没有更新,cache.status===cahce.NOUPDATE

    2)假设cache.manifest已经发生变化,则如下截图所示,不赘述:

     

    五、如何更新离线缓存

    1、本地手动删除,各浏览器实现方式不同。以chrome为例,输入chrome://appcache-internals/,可以查看本地的离线缓存,也可以进行删除

    2、更新.manifest文件,浏览器检测到.manifest变更后,会主动更新本地缓存。(需要注意的是,假如没有更新.manifest,即使你对缓存清单里的文件进行了修改,浏览器依旧会顽强地从本地缓存里面读取修改之前的文件)

    3、通过applicationCache对象的API来主动更新,主要涉及接口为update()以及swapCache()

    cache.update()
    
    官方说明:启动应用缓存下载进程,由于浏览器通常会主动检查.manifest文件确认缓存是否需要更新,所以大部分情况下这个方法是没必要的。但对于一些可能在浏览器里待上长达一个星期左右的应用,比如电子邮箱,这个方法就会排上用场,比如每隔1天检查下本地缓存的一些文件在服务器上是否已经更新。

    个人理解:
    cache.swapCache()
    
    官方说明:如果浏览器已经更新了新的离线缓存,则切到最新的缓存去。对于已经加载解析的资源,如CSS、图片等,并不会导致其重新加载、解析一遍。唯一的变化就是,后续对缓存资源的请求,获取到的都是本地的最新缓存。需要注意的是,swapCache方法需要在updateready事件触发后调用。

    个人理解:调用update方法,更新了本地缓存,但如果不掉用swapCache方法,在本次会话中,重新请求已经更新过的资源,还是拿到老的文件。

     

    、demo演示:update后是否调用swapCache的区别

    假设有cache.html、cache.manifest、cache.js,分别如下:

    cache.html
    <!DOCTYPE html>
    <html lang='cn' manifest='cache.manifest'>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>离线缓存</title>
    </head>
    <body></body>
    <script type="text/javascript" src="cache.js"></script>
    <script type="text/javascript">
    var cache = window.applicationCache;
    conso.log('test:' + test);  //cache.js定义的一个变量,初始值为10
    
    function load(url, callback){
        var script = document.createElement('script');
        script.src = url;
        script.onload = function(){
            callback && callback();
        }
        document.body.appendChild(script);
    }
    
    setTimeout(function(){
        cache.addEventListener('updateready', function(){
            log('更新完毕');
            //cache.swapCache();
            load('cache.js', function(){
                log('test:' + test);    //test: 10
            });    
        });
        cache.update();
    
    }, 20*1000);
    </script>
    </html>
    cache.js
    var test = 10;  //测试用变量
    cache.manifest
    CACHE MANIFEST
    # Javascript v0
    ./cache.js

    假设我们现在已经打开浏览器访问http://localhost/blog/html5/cache/mod_cache/cache.html,在打开页面5s左右后,有人修改了cache.js里变量改test的值,如下:

    var test = 11;  //最初为10,现在修改为11

    同时修改了cache.manifest文件(随便在注释里添加几个数字即可)。之前已经设置了20s后,调用update方法检查缓存资源是否更新,此时浏览器发现cache.manifest文件发生变化,且cache.js的确被修改的,于是毫不犹豫地更新了本地缓存。

    CACHE MANIFEST
    # Javascript v11111
    ./cache.js

    在cache.html里面,将cache.swapCache()这句注释掉了,是否将这句注释掉,是否有差别?差别在哪里?直接看结果:

    1、无cache.swapCache(),输出结果:test: 10

    2、有cache.swapCache(),输出结果:test: 11

    结合API说明不难想到两者之间的差别,当没有调用cache.swapCache()时候,即使重新请求cache.js,加载的还是缓存更新前的cache.js(老的缓存);若调用了cache.swapCache(),则重新请求cache.js时,加载的是已经更新后的cache.js(最新的缓存);

    七、写在后面

    在离线存储的实现方面,似乎不同浏览器理解也不同,最初在chrome下测试的同时,也在firefox下进行测试,然后,不忍心再对比着测试,就挑了据说实现比较靠谱的chrome接着往下测试

    html5离线存储还有很多有意思的东西尚待发掘。自己也是刚刚接触,理解以及文章内容难免存在偏差之处,请谅解并指出。

    参考资料:

    http://i.wanz.im/2010/07/01/html5_offline_file_cache_guide_for_beginner/

    http://www.whatwg.org/specs/web-apps/current-work/#applicationcache

    《HTML5高级程序设计》

  • 相关阅读:
    luogu P4798 [CEOI2015 Day1]卡尔文球锦标赛 dp 数位dp
    7.12 NOI模拟赛 生成树 装压dp vector装压
    2020牛客暑假多校训练营 第二场 H Happy Triangle set 线段树 分类讨论
    2020牛客暑假多校训练营 第二场 G Greater and Greater bitset
    7.11 NOI模拟赛 qiqi20021026的T1 四个指针莫队 trie树
    2020牛客暑假多校训练营 第二场 E Exclusive OR FWT
    7.12 NOI模拟赛 探险队 期望 博弈 dp 最坏情况下最优策略 可并堆
    luogu P5892 [IOI2014]holiday 假期 决策单调性优化dp 主席树
    luogu P2252 威佐夫博弈 模板 博弈
    2020牛客暑期多校训练营 第二场 C Cover the Tree 构造 贪心
  • 原文地址:https://www.cnblogs.com/chyingp/p/explore_html5_cache.html
Copyright © 2011-2022 走看看