JS高程:读书摘要(十九)离线应用与客户端存储
开发离线Web
应用需要几个步骤。首先是确保应用知道设备是否能上网,以便下一步执行正确的操作。然后,应用还必须能访问一定的资源(图像、JavaScript
、CSS
等),只有这样才能正常工作。最后,必须有一块本地空间用于保存数据,无论能否上网都不妨碍读写。HTML5
及其相关的API
让开发离线应用成为现实。
一、离线检测
-
navigator.onLine
属性:这个属性值为true
表示设备能上网,值为false
表示设备离线。 -
ononline
事件和onoffline
事件:当网络从离线变为在线或者从在线变为离线时,分别触发这两个事件。这两个事件在window
对象上触发。
二、应用缓存
HTML5
的应用缓存(application cache
),或者简称为appcache
,是专门为开发离线Web
应用而设计的。Appcache
就是从浏览器的缓存中分出来的一块缓存区。要想在这个缓存中保存数据,可以使用一个描述文件(manifest file
),列出要下载和缓存的资源。下面是一个简单的描述文件示例。
CACHE MANIFEST
#Comment
file.js
file.css
要将描述文件与页面关联起来,可以在<html>
中的manifest
属性中指定这个文件的路径,例如:
<html manifest="/offline.manifest">
// offline.manifest 中包含着描述文件
applicationCache
对象
status
属性,属性的值是常量,表示应用缓存的如下当前状态。
-
0
:无缓存,即没有与页面相关的应用缓存。 -
1
:闲置,即应用缓存未得到更新。 -
2
:检查中,即正在下载描述文件并检查更新。 -
3
:下载中,即应用缓存正在下载描述文件中指定的资源。 -
4
:更新完成,即应用缓存已经更新了资源,而且所有资源都已下载完毕,可以通过swapCache()来使用了。 -
5
:废弃,即应用缓存的描述文件已经不存在了,因此页面无法再访问应用缓存。
事件
-
checking
:在浏览器为应用缓存查找更新时触发。 -
error
:在检查更新或下载资源期间发生错误时触发。 -
noupdate
:在检查描述文件发现文件无变化时触发。 -
downloading
:在开始下载应用缓存资源时触发。 -
progress
:在文件下载应用缓存的过程中持续不断地触发。 -
updateready
:在页面新的应用缓存下载完毕且可以通过swapCache()使用时触发。 -
cached
:在应用缓存完整可用时触发。
一般来讲,这些事件会随着页面加载按上述顺序依次触发。不过,通过调用update()
方法也可以手工干预,让应用缓存为检查更新而触发上述事件。
update()
一经调用,应用缓存就会去检查描述文件是否更新(触发checking
事件),然后就像页面刚刚加载一样,继续执行后续操作。如果触发了cached
事件,就说明应用缓存已经准备就绪,不会再发生其他操作了。如果触发了updateready
事件,则说明新版本的应用缓存已经可用,而此时你需要调用swapCache()
来启用新应用缓存。
三、数据存储
3.1 cookie
Cookie
用于存储 web
页面的用户信息。该标准要求服务器对任意HTTP
请求发送Set-Cookie
HTTP头作为响应的一部分,其中包含会话信息。例如,这种服务器响应的头可能如下:
HTTP/1.1 200 OK
Content-type: text/html
Set-Cookie: name=value
浏览器会存储这样的会话信息,并在这之后,通过为每个请求添加Cookie
HTTP头将信息发送回服务器。
GET /index.html HTTP/1.1
Cookie: name=value
限制
- 个数:
IE7+
和Firefox
每个域最多50个,Opera
最多30个,Safari
和chrome
没有硬性规定。 - 尺寸:
cookie
尺寸限制在4kb
内。 - 超出处理
- 超出个数,
IE
和Opera
会删除最近最少使用的(LRU,Least Recently Used
),Firefox
随机清除某个。 - 超出尺寸,如果你尝试创建超过最大尺寸限制的
cookie
,那么该cookie
会被悄无声息地丢掉。
- 超出个数,
- 避开个数限制
- 可以使用子
cookie
,用一个key
对应多个key&value
键值对字符串。
- 可以使用子
组成
一个cookie
由名称、值、域、路径、失效时间、安全标志几块信息组成。
- 域:
cookie
对于哪个域是有效的。所有向该域发送的请求中都会包含这个cookie
信息。可以包含子域也可以不包含子域。如果没有明确设定,那么这个域会被认作来自设置cookie
的那个域。 - 路径:对于指定域中的那个路径,应该向服务器发送
cookie
。 - 失效时间:表示
cookie
何时应该被删除的时间戳,默认会随着浏览器会话的关闭删除,也可以手动设置,格式需要是GMT
格式的日期,如果设置的是以前的时间,cookie
会被立即删除。 - 安全标志:指定后,
cookie
只有在使用SSL
连接的时候才发送到服务器。
Set-Cookie: name=value; domain=.wrox.com; path=/; secure
尤其要注意,域、路径、失效时间和secure
标志都是服务器给浏览器的指示,以指定何时应该发送cookie
。这些参数并不会作为发送到服务器的cookie
信息的一部分,只有名值对儿才会被发送。
JavaScript
中的cookie
-
document.cookie
:获取cookie
信息或设置cookie
返回当前页面可用的(根据cookie
的域、路径、失效时间和安全设置)所有cookie
的字符串,一系列由分号隔开的名值对儿。设置document.cookie
并不会覆盖cookie
,除非设置的cookie
的名称已经存在。
每次设置cookie
时最好使用encodeURIComponent()
进行编码。删除即设置"expires=" + (new Date(0)).toGMTString();
3.2 Web Storage
window.sessionStorage & window.localStorage
Storage
类型提供最大的存储空间(因浏览器而异)来存储名值对儿,有如下方法。
-
clear()
: 删除所有值;Firefox
中没有实现 。 -
getItem(name)
:根据指定的名字name
获取对应的值。 -
key(index)
:获得index
位置处的值的名字。 -
removeItem(name)
:删除由name
指定的名值对儿。 -
setItem(name, value)
:为指定的name
设置一个对应的值。
可以通过点语法或者方括号语法访问属性,例如sessionStorage.userName
,但是建议使用方法。
还可以通过结合length
属性和key()
方法来迭代或者使用for-in
,如下所示。
for (var i=0, len = sessionStorage.length; i < len; i++){
var key = sessionStorage.key(i);
var value = sessionStorage.getItem(key);
alert(key + "=" + value);
}
for (var key in sessionStorage){
var value = sessionStorage.getItem(key);
alert(key + "=" + value);
}
sessionStorage
会在浏览器关闭后消失,限制大小为2.5M
(IE8+
和Opera
是5M
),存储在sessionStorage
中的数据可以跨越页面刷新而存在,同时如果浏览器支持,浏览器崩溃并重启之后依然可用。
localStorage
localStorage
属于永久存储,限制大小为5M
(chrome
和Safari
是2.5M
),要访问同一个localStorage
对象,页面必须来自同一个域名(子域名无效),使用同一种协议,在同一个端口上。
storage 事件
对Storage
对象进行任何修改,都会在文档上触发storage
事件,这个事件的event
对象有以下属性。
-
domain
:发生变化的存储空间的域名。 -
key
:设置或者删除的键名。 -
newValue
:如果是设置值,则是新值;如果是删除键,则是null
。 -
oldValue
:键被更改之前的值。
有的浏览器并不支持该事件。
3.3 IndexedDB
通俗地说,IndexedDB
就是浏览器提供的本地数据库,它可以被网页脚本创建和操作。IndexedDB
允许储存大量数据,提供查找接口,还能建立索引。这些都是 LocalStorage
所不具备的。就数据库类型而言,IndexedDB
不属于关系型数据库(不支持 SQL
查询语句),更接近NoSQL
数据库。
用于将大量数据储存在客户端,这样可以减少从服务器获取数据,直接从本地获取数据。