客户端存储是指将数据存储在客户端,可以设置存储的有效期。
客户端存储遵循“同源策略”。
主要有以下几种方式:
web存储(localStorage/sessionStorage)、cookie、离线web应用、web数据库
1、localStorage/sessionStorage
- 存储有效期和作用域:
localStorage存储的数据是永久性的,除非web应用刻意删除存储的数据,或用户通过设置浏览器配置来删除;而sessionStorage在窗口或者标签页被永久关闭时,就会被删除,如果同源的文档渲染在不同的标签页中,那么它们拥有各自独立的sessionStorage,无法共享,一个标签页中的脚本是无法读取或覆盖由另一个标签页脚本写入的数据,哪怕这两个标签页打开的是同一个页面
- 存储API:
localStorage.setItem('key','value'); //以key为名字存储一个字段,value必须是string类型
localStorage.getItem('key'); //获取以key为名字的字段
localStorage.removeItem('key'); //移除以key为名的字段
localStorage.clear(); //全部删除
//以上也适用于sessionStorage
- 存储事件:
无论什么时候存储在localStorage或者sessionStorage的数据发生改变,浏览器都会在其它对该数据可见的窗口对象上触发存储事件(但是在对数据进行改变的窗口对象上是不会触发的)。如果浏览器有两个标签页都打开了来自同源的页面,其中一个页面在localStorage上存储了数据,那么另一个标签页就会收到一个存储事件(只有当真正改变时才会触发,如果只是删除一个不存在的数据,或者给已经存在的数据项存储一个一模一样的值,是不会触发的)。
可以通过window.addEventListener()或者window.onstroage属性来注册处理程序,该处理程序的事件对象有5个非常重要的属性
key | 被设置或者移除的项的名字或者键名,如果调用的是clear,则为null |
newValue | 保存该项的新值,调用removeItem时,为null |
oldValue | 改变或者删除该项前的值,当插入一个新值时,为null |
storageArea | 这个属性就好比时window对象上的localStorage属性或sessionStorage属性 |
url | 触发该存储变化脚本所在的文档url |
2、cookie
- 有效期:
cookie默认的有效期很短,它只能持续在web浏览器的会话期间,一旦用户关闭了浏览器,cookie数据就丢失了。如果想延长有效期,可以设置max-age属性,单位是秒,一旦设置了有效期,浏览器就会将cookie数据存储在一个文件中,直到过了有效期再删除
- 作用域:
默认情况下,cookie的作用域和创建它的web页面有关,并对该web页面以及和该web页面同目录或者子目录的其它web页面是可见的,如http://www.example.com/test/index.html创建了一个cookie,则http://www.example.com/test/test2/index.html是可见的,但对http://www.example.com/index.html是不可见的。
可以通过设置cookie的path和domain属性来配置作用域:如果把path设置成'/',则对http://www.example.com下的所有页面都是可见的。如果想要子域之间可以共享cookie,则可以通过domain属性来配置,假如两个子域为:http://www.a.example.com、http://www.b.example.com,此时将path设置为'/',将domain设置为'.example.com',则在example.com下的所有子域都可以共用cookie
- secure属性:
用来表明cookie的值以何种形式通过网络传递,cookie默认以不安全的形式传递,一旦cookie被标志为安全的,则只有浏览器和服务器通过HTTPS或其它的安全协议连接的时候才会传递它
- 保存cookie:
通过document.cookie属性保存cookie
function setcookie(key,value,age,path){
var cookie = key+"="+encodeURIComponent(value);
if(typeof age === number){
cookie+=";max-age="+age;
}
if(path){
cookie+=";path="+path;
}
document.cookie = cookie;
}
3、离线web应用
HTML5中新增了“应用程序缓存”,允许web应用将应用程序自身本地保存到用户的浏览器中。它不会随着用户清除浏览器缓存而被清除,同时缓存起来的应用程序也不会像一般固定大小的缓存那样,老数据会被最新以此访问的新数据代替掉,它其实不是临时存储在缓存中,应用程序更像是被安装在那里,除非被用户卸载或删除它们,否则它们就会一直驻扎在那里,总的来说应用程序缓存在真正意义上不是缓存,更好的说法应该称之为“应用程序存储”。
- 应用程序缓存清单:
想要将应用程序“安装”到应用程序缓存中,首先要创建一个清单;包含了所有应用程序依赖的所有URL列表,然后通过在应用程序注HTML页面的html标签设置manifest属性,指向到该清单文件就可以了:
<html manifest="myapp.appcache">
<head></head>
</html>
//myapp.appcache:必须以CACHE MANIFEST字符串开头,其余就是要缓存的文件URL列表,一行一个URL,注释以#开头
CACHE MANIFEST
myapp.html
myapp.js
myapp.css
image/test.png
tips:清单的扩展名可以修改,只是需要使用.appcache,实际上web服务器是通过text/cache-manifest这个MIME类型来判断是否是清单文件的,如果将Content-Type设置成其它的MIME,则不会缓存应用程序了
复杂的清单:
在清单文件中可以使用特殊的区域头来标识该头信息之后清单项的类型:
CACHE:默认区域,需要缓存的文件
NETWORK:该区域标识了以下URL中的资源从不缓存,总要通过网络获取
FALLBACK:该区域中的每行都包含两个URL,第二个URL是只需要加载和存储在缓存中的资源,第一个URL是前缀,任何能够匹配到该前缀的URL都不会存储起来,它们会从网络中载入,但当从网络中载入失败时,则会使用第二个URL指定的缓存资源来代替。
CACHE MANIFEST
CACHE:
myapp.html
myapp.js
FALLBACK:
videos/ offline_help.html
NETWORK:
cgi/
缓存的更新触发的事件:
缓存更新触发的事件处理程序是注册在ApplicationCache对象上的,该对象是window对象的applicationCache属性的值,通过设置applicationCache的on属性值来注册事件:applicationCache.onchecking = function(){...}
checking | 每当应用程序载入的时候,都会检查该清单文件,此时触发 |
noupdate | 如果清单文件没有改变,同时应用程序已经缓存了,触发该事件 |
downloading | 如果还未缓存应用程序,或者清单文件有改动,那么浏览器会下载并缓存清单中的资源,触发该事件,意味中下载过程开始 |
progress | 在下载过程中会间断性的触发progress事件 |
cached | 当下载完成并且首次将应用程序下载到缓存中时 |
updateready | 当下载完成并将缓存中的应用程序更新后,触发该事件 |
error | 如果浏览器处于离线状态,检查清单列表失败,或者当一个未缓存的应用程序引用一个不存在的清单文件,则触发error |
obsolete | 如果一个缓存的应用程序引用一个不存在的清单文件,会触发该事件,同时会将应用程序从缓存中清除 |