HTML5离线存储整理

2017-01-10 janeta0001

前端html部分

//canvas.html
<!DOCTYPE html>
<html manifest="/test.appcache">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>浏览器离线存储</title>
</head>
<body>
    <div >
        <img src="/photos/touxiang.jpg" />
        <img id='hgk' src="/photos/canvas.png" />
    </div>
 </body>
</html>

配置文件

CACHE MANIFEST
#v1.0.5
#需要缓存的文件
CACHE:
/photos/canvas.png
#不需要缓存的文件
NETWORK:
*
#无法访问页面
FALLBACK:
404.html

服务器端node.js

app.js
var express = require('express'); 
var app = express();
var path = require('path');
var join = path.join;
var ejs = require('ejs')    //ejs模板
var fs = require("fs");     //fs模块
var bodyParser = require('body-parser');    //解析post请求模块
var favicon = require('serve-favicon');
var events = require("events");
var emitter = new events.EventEmitter()

app.set('views', __dirname+'/views');
app.disable('view cache'); //解除视图缓存
app.engine('.html', ejs.__express);
app.set('view engine', 'html')
app.use(express.static(path.join(__dirname,'public'))); //设置静态文件夹
app.use(bodyParser.urlencoded({ extended: false }));
app.use(favicon(__dirname + '/favicon.ico'));
app.use(function(req,res,next){
    if(req.url=='/test.appcache'){
        res.setHeader('content-type','text/cache-manifest');
    };
    next();
})
app.get('/canvas',function(req,res){
    res.sendFile( __dirname + "/views/" + "canvas.html" );
})
app.listen(8081,function(){
    console.log('success connect')
})

第一次加载页面时候(需联网)

第二次加载页面的时候(离线加载)


我们设置离线缓存的图片在无网络情况下能够正常从缓存中访问。
离线缓存中的坑:
清单文件经过修改。请注意:更新清单中列出的某个文件并不意味着浏览器会重新缓存该资源。清单文件本身必须进行更改。
1.查看缓存状态

var appCache = window.applicationCache;  
switch (appCache.status) {  
  case appCache.UNCACHED: // UNCACHED == 0  
    return 'UNCACHED';  
    break;  
  case appCache.IDLE: // IDLE == 1  
    return 'IDLE';  
    break;  
  case appCache.CHECKING: // CHECKING == 2  
    return 'CHECKING';  
    break;  
  case appCache.DOWNLOADING: // DOWNLOADING == 3  
    return 'DOWNLOADING';  
    break;  
  case appCache.UPDATEREADY:  // UPDATEREADY == 4  
    return 'UPDATEREADY';  
    break;  
  case appCache.OBSOLETE: // OBSOLETE == 5  
    return 'OBSOLETE';  
    break;  
  default:  
    return 'UKNOWN CACHE STATUS';  
    break;  
};  

2.更新浏览器缓存

var appCache = window.applicationCache;  
appCache.update(); // Attempt to update the user's cache.  
...  
if (appCache.status == window.applicationCache.UPDATEREADY) {  
  appCache.swapCache();  // The fetch was successful, swap in the new cache.  
}  

请注意:以这种方式使用 update() 和 swapCache() 不会向用户提供更新的资源。此流程只是让浏览器检查是否有新的清单、下载指定的更新内容以及重新填充应用缓存。因此,还需要对网页进行两次重新加载才能向用户提供新的内容,其中第一次是获得新的应用缓存,第二次是刷新网页内容。
好消息是,您可以避免重新加载两次的麻烦。要使用户更新到最新版网站,可设置监听器,以监听网页加载时的 updateready 事件:

//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();  
      if (confirm('A new version of this site is available. Load it?')) {  
        window.location.reload();  
      }  
    } else {  
      // Manifest didn't changed. Nothing new to server.  
    }  
  }, false);  
}, false);  

由于离线缓存会默认缓存html页面,所以对于动态html输出的页面例如(php,jsp)等来说使用离线缓存会出现很多问题, 根据Application Cache的加载机制,如果仅仅修改资源文件的内容(没有修改资源文件的路径或名称),浏览器将直接从本地离线缓存中获取资源文件。所以在每次修改资源文件的同时,需要修改manifest文件,以触发资源文件的重新加载和缓存。这其中,最有效的方式是修改manifest文件内部的版本注释(所以说那句注释相当重要) 如果资源没有被缓存,在而没有设置NETWORK的情况下,将会无法加载(浏览器不会去网络上进行加载),所以需要使用通配符来表明除了CACHE中确定的资源以外,其他资源都需要去网络上加载。

参考文章
http://blog.csdn.net/fwwdn/ar...
离线缓存坑:http://www.th7.cn/web/html-cs...

内容来源:https://segmentfault.com/a/1190000008059199


用户评论
开源开发学习小组列表