HTML5离线应用与客户端存储
序言
本篇文章会详细介绍使用HTML5开发离线应用的步骤,以及本地存储与cookie的一些异同,最后利用上面所学例子来实现一个购物车场景。
使用HTML5离线存储的基本过程如下:
离线检测:首先要对设备进行离线状态检测,根据设备在线或者离线判断接下来的操作;
离线缓存:将需要被缓存的资源写在一个描述文件(cache manifest)里,当设备在线时进行缓存,以便用户在离线时可以正常使用;
本地存储:离线时,把必要的数据存储到本地,当设备上线时将数据存储到服务器上。
下面就从这三个方面展开进行介绍。
离线检测
开发离线应用首先要检测设备的状态,根据设备在线或者离线进行接下来的操作。HTML5为我们提供了两种判断设备在线状态的方式:属性navigator.onLine和事件online/offline。
为了检测应用是否离线,我们可以通过navigator.onLine判断设备的初始状态,同时通过online/offline事件来确定网络的连接状态是否变化。online/offline事件首先在body上触发,随后会沿着document.body, document, window的顺序冒泡,所以我们可以对它们进行监听获得设备的状态变化。
if(navigator.onLine){
//正常工作
}
else{
//执行离线事件处理程序
}
window.addEventListener('online', function(){
//进行离线缓存
});
window.addEventListener('offline', function(){
//使用离线缓存
})
离线缓存
描述清单
通过离线检测,我们需要在设备在线时对需要的文件进行缓存。HTML5 的应用缓存(application cache),或者简称为appcache,是专门为开发离线Web应用而设计的。Appcache 就是从浏览器的缓存中分出来的一块缓存区。要想在这个缓存中保存数据,可以使用一个描述文件(manifest file),列出要下载和缓存的资源。下面是一个简单的描述文件示例。
CACHE MANIFEST
#上面的声明必不可少 index.html
common.css NETWORK:
*.html CACHE:
login.html FALLBACK:
*.html offline.html
/project /offline/project
描述文件的基本格式如下:
- CACHE MANIFEST书写在第一行,而且必不可少;
- #开头代表注释;
- CACHE标识符:这是条目的默认部分。系统会在首次下载此标头下列出的文件(或紧跟在
CACHE MANIFEST后的文件)后显式缓存这些文件; - NETWORK标识符:代表“白名单”,它表示的是无论在线离线都需要联网访问的文件;
- FALLBACK标识符:此部分是可选的,用于指定无法访问资源时的后备网页。其中第一个 URI 代表资源,第二个代表后备网页。两个 URI 必须相关,并且必须与清单文件同源。可使用通配符。
在声明好描述文件的后,需要将描述文件与页面关联起来。在文档的 html 标记中添加 manifest 属性:
<html manifest='/offline.manifest'>
注1:描述文件扩展名以前推荐使用manifest,但现在推荐的是appcache。
注2:网站的应用缓存数据量不得超过5MB。
注3:系统会自动缓存引入描述清单的HTML文件,不过还是建议将其写入到描述清单中。
更新缓存
浏览器除了在第一次访问 Web 应用时缓存资源外,只有在以下三种情况才会对缓存进行更新:
- 浏览器缓存被删除
- manifest描述文件本身发生变化
- 应用缓存通过编程方式进行更新
而cache manifest中的资源文件发生变化并不会触发更新,所以在对资源进行更改后,需要向描述文件中加入时间戳或版本号。
要以编程方式对缓存进行更新,需要用到缓存对象window.applicationCache。可以使用它的属性window.applicationCache来判断缓存状态,全部状态如下:
- 0:UNCACHED-没有与页面相关的应用缓存
- 1:IDLE-应用缓存未更新
- 2:CHECKING-正在检查描述文件是否更新
- 3:DOWNLOADING-下载中
- 4:UPDATEREADY-更新完成
- 5:OBSOLETE-描述文件不存在了,不能获取应用缓存
比较常用的缓存状态UPDATEREADY,当判断缓存更新完成,就可以对浏览器应用缓存,并进行刷新。与之相同的还有缓存事件:
- checking:浏览器在为应用缓存查找更新时触发
- error:查找错误时触发
- noupdate:检查后发现描述文件无变化时触发
- downloading:开始下载应用缓存资源时触发
- progress:在下载应用缓存资源时不断的触发
- updateready:应用缓存已经更新完毕,此时可以手动触发swapCache()应用更新的缓存
- cached:在应用缓存完整可用时触发
一般来讲,这些事件会随着页面加载按上述顺序依次触发。不过,通过调用 update()方法也可以手工干预,让应用缓存为检查更新而触发上述事件。在调用update()后,我们通常使用updateready()和swapCache(),实现对浏览器缓存的更新,具体步骤如下:
window.applicationCache.update(); //手动检测更新
window.applicationCache.addEventListener('updateready', function(){
if(window.applicationCache.status == window.applicationCache.UPDATEREADY){
window.applicationCache.swapCache(); //应用更新
if(confirm('是否应用新的缓存?')){
window.location.reload(); //刷新页面
}
}
else{
//没有缓存更新
}
})
注:You can programmatically test to see if an application has an updated cache manifest file, using JavaScript. Since a cache manifest file may have been updated before a script attaches event listeners to test for updates, scripts should always test window.applicationCache.status.
本地存储
Cookie
Cookie是最基础的存储方式,主要用于服务器对用户登陆的判断。服务器会对每一个HTTP请求发送Set-Cookie作为HTTP头的一部分,浏览器会保存该部分内容,并在之后的每个请求头中加入该Cookie,以便服务器识别请求的来源。
Cookie由名字,值,域,路径,失效时间和安全标志组成。其中域和路径发送该Cookie的地址;失效时间是表示该Cookie何时被删除的时间戳(默认情况下,浏览器会在回话关闭时删除所有Cookie,不过我们也可以自己设置删除时间);而指定安全标志后,Cookie只有通过SSL连接才能传输。大体结构如下:
HTTP/1.1200 OK
Content-type: text/html
Set-Cookie: name=value; expires=Mon,22-Jan-0707:10:24 GMT; domain=.wrox.com; path=/; secure
Other-header: other-header-value
我们可以使用BOM提供的接口document.cookie来设置Cookie,上述参数中只有name/value是必选项,只要name没有重复,为cookie赋值是不会覆盖已有信息的。不过这样做有点蹩脚,就像下面的代码一样:
document.cookie = encodeURIComponent('name') + '=' + encodeURIComponent('pansy');
所以我们通常为Cookie封装新的函数来进行操作,下面封装实现了对Cookie值的增删和查询,可以把这种常用操作加入到自己的库里:
var CookieUtil = {
set: function(name, value, domain, path, expires, secure){ //前两个是必填的
var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value);
if(domain){
cookieText += '; domain=' + encodeURIComponent(domain);
}
if(path){
cookieText += '; path=' + encodeURIComponent(path);
}
if(expires instanceof Date){
cookieText += '; expires=' + expire.toGMTString;
}
if(secure){
cookieText += '; secure';
}
document.cookie = cookieText;
},
get: function(name){
cookieName = encodeURIComponent(name); //一定不要忘记进行URL编码
cookieStart = document.cookie.indexOf(name);
cookieValue = null;
if(cookieStart != -1){
cookieEnd = document.cookie.indexOf(';', cookieStart);
if(cookieEnd == -1){
cookieEnd = document.cookie.length;
}
cookieValue = document.cookie.slice(cookieStart, cookieEnd); //或者使用string.prototype.substring
}
return cookieValue;
},
del: function(name){
this.set(name,"",new Date(0))
}
}
由于所有的 cookie 都会由浏览器作为请求头发送,所以在 cookie 中存储大量信息会影响到特定域的请求性能。 cookie 信息越大,完成对服务器请求的时间也就越长。尽管浏览器对 cookie 进行了大小限制,不过最好还是尽可能在 cookie 中少存储信息,以避免影响性能。
cookie 的性质和它的局限使得其并不能作为存储大量信息的理想手段,所以又出现了其他方法。
Storage
cookie提供的本地存储空间十分有限(要不然怎么叫小饼干呢~),通常只有几K,所以HTML5引用了Storage来进行本地存储,Storage 类型提供最大的存储空间来存储名值对儿(key/value)。DOM Storage 分为两类:sessionStorage 和 localStorage。除了以下区别外,这两类存储对象的功能是完全一致的(因为它们同属一种Storage类型)。
- sessionStorage 用于存储与当前浏览器窗口关联的数据。窗口关闭后,sessionStorage 中存储的数据将无法使用。
- localStorage 用于长期存储数据。窗口关闭后,localStorage 中的数据仍然可以被访问。所有浏览器窗口可以共享 localStorage 的数据。
对Storage的操作可以通过方法或者属性来实现,下面以localStorage为例,sessionStorage与之相同:
//设置、读取、删除变量
//使用方法
localStorage.setItem("name", "Pansy");
var name = localStorage.getItem("name")
localStorage.removeItem("name"); //使用属性
localStorage.book ="Professional Javascript";
var book = localStorage.book;
remove localStorage.book;
备忘录实例
使用HTML5本地存储做了一个备忘录的实例,如下图所示,进一步的代码可以在GitHub上获取:

参考文章:
HTML5 localStorage本地存储实际应用举例 « 张鑫旭
HTML5离线应用与客户端存储的更多相关文章
- js-新兴的API,最佳实践,离线应用于客户端存储
离线应用于客户端存储: 1.离线检测:online以及offline事件,都是在window对象上触发 navigator.online为true的时候是表示设备能够上网 2.使用一个描述文件(man ...
- 离线应用与客户端存储(cookie storage indexedDB)
离线检测 HTML5定义一个属性:navigator.onLine的属性.这个属性值为true,表示设备在线,值为false,表示设备离线.为了更好的确定网络是否可用,HTML5还定义了两个事件.这两 ...
- 《javascript高级程序设计》 第23章 离线应用与客户端存储
23.1 离线检测23.2 应用缓存23.3 数据存储 23.3.1 Cookie 23.3.2 IE 用户数据 23.3.3 Web 存储机制 23.3.4 IndexedDB 23.1 离线检 ...
- HTML5学习笔记之客户端存储数据方法:localStorage(),sessionStorage()
HTML5提供了两种在客户端存储数据的新方法: localStorage():没有时间限制的数据存储 sessionStorage():针对一个session的数据存储 下面的一个例子用localSt ...
- JavaScript中离线应用和客户端存储(cookies、sessionStorage、localStorage)
一.离线应用 所谓离线web应用,就是在设备不能上网的情况下仍然可以运行的应用. 开发离线web应用需要几个步骤:首先,确保应用知道设备是否能上网,以便下一步执行正确的操作:然后,应用还必须能访问一定 ...
- 【JavaScript】离线应用与客户端存储
一.前言 这章非常重要,由于之后需要负责平台手机APP的日后维护,如何让用户在离线状态下正常使用,以及联网后的数据合并变得非常重要. 二.内容 离线检测 navigator ...
- HTML5的五种客户端离线存储方案
最近折腾HTML5游戏需要离线存储功能,便把目前可用的几种HTML5存储方式研究了下,基于HT for Web写了个综合的实例,分别利用了Cookie.WebStorage.IndexedDB以及Fi ...
- 【html5】html5离线存储
html5本地存储之离线存储 1.为什么使用离线存储 ①最新的主流的浏览器中都已添加了对HTML5的offline storage功能的支持,HTML5离线存储功能非常强大, 它的作用是:在用户没有与 ...
- 吓哭原生App的HTML5离线存储技术,却出乎意料的容易!【低调转载】
吓哭原生App的HTML5离线存储技术,却出乎意料的容易![WeX5低调转载] 2015-11-16 lakb248 起步软件 近几天,WeX5小编编跟部分移动应用从业人士聊了聊,很多已经准备好全面拥 ...
随机推荐
- Python基础学习3---数据结构
数据结构 数据结构基本上就是---他们是可以处理数据的结构或者说他们是用来存储一组相关数据的. 在python中有三种内建的数据结构-----列表.元组和字典 列表(list) 列表就像是我们要去超市 ...
- 更方便的函数回调——Lambda
auto callbackFunc = [&](){ backHome(); }; []符号,表示要开始一个lambda函数: ()符号,里面填写函数的参数: 当想在lambda函数里使用外部 ...
- angularJS Directive学习
Directive 指令 直接上实例 index.html <!doctype html> <html ng-app="drag"> <head> ...
- linux下的vim使用笔记
环境:window下可以使用gvim编辑软件 学习主要是在ubuntu15敲击命令学习的视频来自于智普教育vim使用视频1. sudo apt show vi 查看安装的vi版本,当然了我的ubunt ...
- JS中三目运算符和if else的区别分析与示例
本文是通过示例详细分析了JS中三目运算符和if else的区别,是篇非常不错的文章,这里推荐给大家. 今天写了一个图片轮播的小demo,用到了判断 先试了一下if else,代码如下: 复制代码代 ...
- 去掉tomcat中appBase默认的ROOT
我想修改tomcat的项目目录,写成绝对路径后,默认去找ROOT文件夹 怎么去掉呢 <Host name="localhost" appBase="E:\ceshi ...
- VI中的批量替换 (转载)
1) 文件内全部替换: :%s#abc#123#g (如文件内有#,可用/替换,:%s/abc/123/g) --注:把abc替换成123 (或者: %s/str1/str2/g 用s ...
- Java中的回调函数学习
Java中的回调函数学习 博客分类: J2SE JavaJ# 一般来说分为以下几步: 声明回调函数的统一接口interface A,包含方法callback(); 在调用类caller内将该接口设置 ...
- PHP聊天室开源系统workerman-chat
PHP聊天室开源系统workerman-chat (2015-01-23 09:07:50) 转载▼ http://www.workerman.net/ http://www.workerman.ne ...
- 行内元素为何不能设置margin-top、margin-bottom;padding-top、padding-bottom值
曾经学过的教程中写明:行内元素的特点有: 1.与其他元素在同一行 2.宽度(width).高度(height).内边距的top/bottom(padding-top/padding-bottom)和外 ...