html5 local storage and session storage

from here:

html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage。

sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储。

localStorage用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。

web storage和cookie的区别

Web Storage的概念和cookie相似,区别是它是为了更大容量存储设计的。Cookie的大小是受限的,并且每次你请求一个新的页面的时候Cookie都会被发送过去,这样无形中浪费了带宽,另外cookie还需要指定作用域,不可以跨域调用。

除此之外,Web Storage拥有setItem,getItem,removeItem,clear等方法,不像cookie需要前端开发者自己封装setCookie,getCookie。

但是Cookie也是不可以或缺的:Cookie的作用是与服务器进行交互,作为HTTP规范的一部分而存在 ,而Web Storage仅仅是为了在本地“存储”数据而生(来自@otakustay 的纠正)

html5 web storage的浏览器支持情况

浏览器的支持除了IE7及以下不支持外,其他标准浏览器都完全支持(ie及FF需在web服务器里运行),值得一提的是IE总是办好事,例如IE7、IE6中的UserData其实就是javascript本地存储的解决方案。通过简单的代码封装可以统一到所有的浏览器都支持web storage。

要判断浏览器是否支持localStorage可以使用下面的代码:

if(window.localStorage){     alert("浏览支持localStorage") }else{    alert("浏览暂不支持localStorage") } //或者 if(typeof window.localStorage == 'undefined'){ 	alert("浏览暂不支持localStorage") }

localStorage和sessionStorage操作

localStorage和sessionStorage都具有相同的操作方法,例如setItem、getItem和removeItem等

localStorage和sessionStorage的方法

setItem存储value

用途:将value存储到key字段
用法:.setItem( key, value)
代码示例:

	sessionStorage.setItem("key", "value"); 	localStorage.setItem("site", "js8.in");
getItem获取value

用途:获取指定key本地存储的值
用法:.getItem(key)
代码示例:

	var value = sessionStorage.getItem("key"); 	var site = localStorage.getItem("site");
removeItem删除key

用途:删除指定key本地存储的值
用法:.removeItem(key)
代码示例:

	sessionStorage.removeItem("key"); 	localStorage.removeItem("site");
clear清除所有的key/value

用途:清除所有的key/value
用法:.clear()
代码示例:

	sessionStorage.clear(); 	localStorage.clear();
其他操作方法:点操作和[]

web Storage不但可以用自身的setItem,getItem等方便存取,也可以像普通对象一样用点(.)操作符,及[]的方式进行数据存储,像如下的代码:

var storage = window.localStorage; storage.key1 = "hello"; storage["key2"] = "world"; console.log(storage.key1); console.log(storage["key2"]);
localStorage和sessionStorage的key和length属性实现遍历

sessionStorage和localStorage提供的key()和length可以方便的实现存储的数据遍历,例如下面的代码:

var storage = window.localStorage; for (var i=0, len = storage.length; i  <  len; i++){     var key = storage.key(i);     var value = storage.getItem(key);     console.log(key + "=" + value); }

storage事件

storage还提供了storage事件,当键值改变或者clear的时候,就可以触发storage事件,如下面的代码就添加了一个storage事件改变的监听:

if(window.addEventListener){ 	window.addEventListener("storage",handle_storage,false); }else if(window.attachEvent){ 	window.attachEvent("onstorage",handle_storage); } function handle_storage(e){ 	if(!e){e=window.event;}	 }

storage事件对象的具体属性如下表:

PropertyTypeDescription
keyStringThe named key that was added, removed, or moddified
oldValueAnyThe previous value(now overwritten), or null if a new item was added
newValueAnyThe new value, or null if an item was added
url/uriStringThe page that called the method that triggered this change

Web Storage Demo

HTML5 Demos: Storage     Web Storage Example

标签:  yuzhongwusanHTML5前端开发
24
0
请先 登录
« 上一篇: Aptana Studio 3 如何汉化,实现简体中文版
» 下一篇: HTML5 LocalStorage 本地存储



HTML5 LocalStorage 本地存储

说到本地存储,这玩意真是历尽千辛万苦才走到HTML5这一步,之前的历史大概如下图所示:

 

最早的Cookies自然是大家都知道,问题主要就是太小,大概也就4KB的样子,而且IE6只支持每个域名20cookies,太少了。优势就是大家都支持,而且支持得还蛮好。很早以前那些禁用cookies的用户也都慢慢的不存在了,就好像以前禁用javascript的用户不存在了一样。

 

userDataIE的东西,垃圾。现在用的最多的是Flash吧,空间是Cookie25倍,基本够用。再之后Google推出了Gears,虽然没有限制,但不爽的地方就是要装额外的插件(没具体研究过)。到了HTML5把这些都统一了,官方建议是每个网站5MB,非常大了,就存些字符串,足够了。比较诡异的是居然所有支持的浏览器目前都采用的5MB,尽管有一些浏览器可以让用户设置,但对于网页制作者来说,目前的形势就5MB来考虑是比较妥当的。



支持的情况如上图,IE8.0的时候就支持了,非常出人意料。不过需要注意的是,IEFirefox测试的时候需要把文件上传到服务器上(或者localhost),直接点开本地的HTML文件,是不行的。

 

首先自然是检测浏览器是否支持本地存储。在HTML5中,本地存储是一个window的属性,包括localStoragesessionStorage,从名字应该可以很清楚的辨认二者的区别,前者是一直存在本地的,后者只是伴随着session,窗口一旦关闭就没了。二者用法完全相同,这里以localStorage为例。

if(window.localStorage){
 alert('This browser supports localStorage');
}else{
 alert('This browser does NOT support localStorage');
}

 

存储数据的方法就是直接给window.localStorage添加一个属性,例如:window.localStorage.a 或者 window.localStorage["a"]。它的读取、写、删除操作方法很简单,是以键值对的方式存在的,如下:

localStorage.a = 3;//设置a"3"
localStorage["a"] = "sfsf";//设置a"sfsf",覆盖上面的值
localStorage.setItem("b","isaac");//设置b"isaac"
var a1 = localStorage["a"];//获取a的值
var a2 = localStorage.a;//获取a的值
var b = localStorage.getItem("b");//获取b的值
localStorage.removeItem("c");//清除c的值

 

这里最推荐使用的自然是getItem()setItem(),清除键值对使用removeItem()。如果希望一次性清除所有的键值对,可以使用clear()。另外,HTML5还提供了一个key()方法,可以在不知道有哪些键值的时候使用,如下:

var storage = window.localStorage;
function showStorage(){
 for(var i=0;i<storage.length;i++){
  //key(i)获得相应的键,再用getItem()方法获得对应的值
  document.write(storage.key(i)+ " : " + storage.getItem(storage.key(i)) + "<br>");
 }
}

 

写一个最简单的,利用本地存储的计数器:

var storage = window.localStorage;
if (!storage.getItem("pageLoadCount")) storage.setItem("pageLoadCount",0);
storage.pageLoadCount = parseInt(storage.getItem("pageLoadCount")) + 1;//必须格式转换
document.getElementByIdx_x("count").innerHTML = storage.pageLoadCount;
showStorage();

不断刷新就能看到数字在一点点上涨,如下图所示:

 

需要注意的是,HTML5本地存储只能存字符串,任何格式存储的时候都会被自动转为字符串,所以读取的时候,需要自己进行类型的转换。这也就是上一段代码中parseInt必须要使用的原因。

 

另外,在iPhone/iPad上有时设置setItem()时会出现诡异的QUOTA_EXCEEDED_ERR错误,这时一般在setItem之前,先removeItem()ok了。

 

HTML5的本地存储,还提供了一个storage事件,可以对键值对的改变进行监听,使用方法如下:

if(window.addEventListener){
 window.addEventListener("storage",handle_storage,false);
}else if(window.attachEvent){
 window.attachEvent("onstorage",handle_storage);
}
function handle_storage(e){
 if(!e){e=window.event;}
 //showStorage();
}

 

对于事件变量e,是一个StorageEvent对象,提供了一些实用的属性,可以很好的观察键值对的变化,如下表:

 Property

 Type

 Description

 key

 String

 The named key that was added, removed, or moddified

 oldValue

 Any

 The previous value(now overwritten), or null if a new item was added

 newValue

 Any

 The new value, or null if an item was added

 url/uri

 String

 The page that called the method that triggered this change

 

这里添加两个键值对ab,并增加一个按钮。给a设置固定的值,当点击按钮时,修改b的值:

<body>
<p>You have viewed this page <span id="count">0</span>  time(s).</p>
<p><input type="button" value="changeStorage" onClick="changeS()"/></p>
<script>
var storage = window.localStorage;
if (!storage.getItem("pageLoadCount")) storage.setItem("pageLoadCount",0);
storage.pageLoadCount = parseInt(storage.getItem("pageLoadCount")) + 1;//必须格式转换
document.getElementByIdx_x("count").innerHTML = storage.pageLoadCount;
showStorage();
if(window.addEventListener){
 window.addEventListener("storage",handle_storage,false);
}else if(window.attachEvent){
 window.attachEvent("onstorage",handle_storage);
}
function handle_storage(e){
 if(!e){e=window.event;}
 showObject(e);
}
function showObject(obj){
 //递归显示object
 if(!obj){return;}
 for(var i in obj){
  if(typeof(obj[i])!="object" || obj[i]==null){
   document.write(i + " : " + obj[i] + "<br/>");
  }else{
   document.write(i + " : object" + "<br/>");
  }
 }
}
storage.setItem("a",5);
function changeS(){
 //修改一个键值,测试storage事件
 if(!storage.getItem("b")){storage.setItem("b",0);}
 storage.setItem('b',parseInt(storage.getItem('b'))+1);
}
function showStorage(){
 //循环显示localStorage里的键值对
 for(var i=0;i<storage.length;i++){
  //key(i)获得相应的键,再用getItem()方法获得对应的值
  document.write(storage.key(i)+ " : " + storage.getItem(storage.key(i)) + "<br>");
 }
}
</script>
</body>

 

测试发现,目前浏览器对这个支持不太好,仅iPadFirefox支持,而且Firefox支持得乱糟糟,e对象根本没有那些属性。iPad支持非常好,用的是e.uri(不是e.url),台式机上的Safari不行,诡异。

 

目前浏览器都带有很好的开发者调试功能,下面分别是ChromeFirefox的调试工具查看LocalStorage



另外,目前javascript使用非常多的json格式,如果希望存储在本地,可以直接调用JSON.stringify()将其转为字符串。读取出来后调用JSON.parse()将字符串转为json格式,如下所示:

var details = {author:"isaac","description":"fresheggs","rating":100};
storage.setItem("details",JSON.stringify(details));
details = JSON.parse(storage.getItem("details"));

 

JSON对象在支持localStorage的浏览器上基本都支持,需要注意的是IE8,它支持JSON,但如果添加了如下的兼容模式代码,切到IE7模式就不行了(此时依然支持localStorage,虽然显示window.localStorage[object],而不是之前的[object Storage],但测试发现getItem()setItem()等均能使用)。

<meta content="IE=7" http-equiv="X-UA-Compatible"/>

标签:  yuzhongwusanHTML5前端开发
1
0
« 上一篇: HTMl5的sessionStorage和localStorage
» 下一篇: 解构JavaScript库:jQuery、Prototype、Mootools
posted on  2011-12-19 14:45  yuzhongwusan 阅读( 1045) 评论( 0编辑 





HTML5 Local Storage( 本地存储) 的前世今生

原文连接:http://diveintohtml5.org/storage.html    (深入HTML5)

作者:Mark Pilgrim

译者 : feijia (tiimfei@gmail.com)


译者的话:上周读到这篇关于html5 local storage  的综述性文章觉得十分受益。这篇文章是作者的书HTML5 up & Running的的一个章节,并在线以 CC-BY-3.0 License授权。  可以看到dojox.storage 是在HTML5标准成型前整个业界唯一提供统一的本地存储接口的框架。 即使是在今天,为了兼顾用户较早版本浏览器的兼容性,dojox.storage 仍然有很大的作用. 文章较长,分两部分翻译。 今天是第一部分。


长久以来本地存储能力一直是桌面应用区别于Web应用的一个主要优势.对于桌面应用(或者原生应用),操作系统一般都提供了一个抽象层用来帮助应用程序保存其本地数据

例如(用户配置信息或者运行时状态等). 常见的存放这些数据的方式有许多: 注册表,INI文件,XML文件等等。 除了上面这些比较简单的用来存放 键值对的存储形式,如
果你需要使用更加复杂强大的存储,那么你还可以进一步在应用程序中嵌入小型数据库,或者开发出特定的数据文件格式。

遗憾的是,上面这些本地存储方法对Web应用来说都是不适用的。在Web的发展史上,在很长时间里 Cookies是唯一可以使用的在用户本地存储少量数据的方法。 但Cookies有一些非常明显的缺陷,限制了它的应用:

1. cookie会被附加在每个HTTP请求中,所以无形中增加了流量。

2. 由于在HTTP请求中的cookie是明文传递的,所以安全性成问题。 (除非你的整个应用都是使用SSL来构建的)
3. Cookie的大小限制在4 KB左右。 对于复杂的存储需求来说是不够用的。


对于开发者来说,他们真正需要的是

1. 不受限的存储空间

2. 数据保存在客户端

3. 数据的生命周期可以跨越页面的刷新(甚至浏览器关闭重新打开)

4. 本地数据不必每次都被重复的传回服务器而导致流量增加

在HTML5之前,为了达成上述目标,人们开发出了许多方法,但是总是有一些不尽人意之处。 

在HTML5之前的本地存储的简史


在互联网发展早期,浏览器市场还很单一(处在领先地位的只有Netscape浏览器和IE)。在 第一次浏览器大战 中,微软的IE为了争取更大的份额,它自己发明了许多额外附加的功能。 这些功能就包括 动态HTML (DHTML)  , 而动态HTML中就包含了一种称为 userData 的技术。


userData 允许网页存储最大64KB的基于XML的结构化数据(每个站点) 。获信的站点,例如内网站点,可使用的存储量可以增大到10倍,也即640K。 在使用userData时,IE不会弹出任何形式的对话框来要求用户授权,也不允许程序增加本地存储的容量。


在2002年,Adobe(译者:那个时候其实应该是 Macromedia ) 在Flash6中引入了一个新的本地存储功能,并命名为“Flash Cookies"。 这个名称十分具有迷惑性,其实跟cookie没什么关系。 在Flash中,这个功能被称作  Local Shared Objects  。 简单来说,这个技术允许Flash 对象存储100KB的数据(每个站点 )。 基于此, Brad Neuberg 开发了一个称为  AMASS (AJAX Massive Storage System) Ajax大容量存储系统)的 Flash到JavaScript的桥接原型接口,允许开发者在JavaScript中调用LSO,但是由于Flash的种种技术局限,这个原型并不大好用。 到2006年,随着Flash 8 引入了 ExternalInterface 技术,在JavaScript中访问LSO对象变得简化了许多。这时Brad重写了AMASS并把它整合到了流行的 Dojo Toolkit  框架中, 并正式命名为dojox.storage。 Flash的这种技术允许每个站点存储100KB的数据,超过100KB,则每增加超过一个数量级(如1MB, 10MB 等),它就会弹出对话框来要用户确认并授权。


在2007年,Google启动了著名的 Gears 项目, Gears是一个通过插件技术来增强浏览器功能的开源项目。 Gears提供了一套 API 来访问一个基于 SQLite 的嵌入式SQL数据库, 在获得用户的一次性授权后,应用程序可以通过Gears存储不限数量的本地数据。 

与此同时, Brad Neuberg 和其他人继续开发dojox.storage , 希望能够提供一套统一的JavaScript接口来封装上面各种插件和接口。 到2009年时, dojox.storage 已经可以做到自动的侦测用户浏览器所支持的本地存储技术,并提供统一的访问接口,包括Adobe Flash, Adobe AIR, Gears 以及早期 Firefox浏览器所提供的HTML5 存储功能。

从我们前面的介绍可以看到这些五花八门的技术都有一个问题,他们要么是某个浏览器所特有的技术,要么依赖于某个第三方插件(flash或Gears). 虽然Dojox.storage非常有远见的试图去封装这些区别,但是用户仍然会因为底层技术的限制而在用户体验,允许存储的数据量等方面无法统一。 这时,只有HTML5标准的出现才能彻底解决这些问题:  提供一套标准化的API, 被绝大多数浏览器支持,不用依赖任何第三方插件。 



HTML5 本地存储简介


这里我们称为HTML Storage的实际上是一个称为  Web Storage   的标准, 它原来曾是HTML5标准的一部分,但由于某些政治因素,现在它被独立出来。  某些浏览器厂商也称它为 本地存储(local storage),或者DOM存储 (DOM Storage)

那么究竟什么是HTML5本地存储 ? 简单来说,它就是一种让网页可以把键值对存储在用户浏览器客户端的方法。像Cookie一样,这些数据不会因为你打开新网站,刷新页面,乃至关闭你的浏览器而消失。 而与Cookie不同的时,这些数据不会每次随着HTTP请求被发送到服务器端(当然如果你需要这么做,你可以自己编程实现 ). 因为这是HTML5规范的一部分,这一接口会被浏览器原生支持,不用依赖任何第三方插件。 

那么,现在有哪些浏览器支持这一接口呢? 在这篇文章写作时(译者:2011年2月) 差不多所有主流浏览器的最新版都支持了,连IE8都支持了。 
HTML5 Storage support
IEFirefoxSafariChromeOperaiPhoneAndroid
8.0+3.5+4.0+4.0+10.5+2.0+2.0+


在你的JS代码中,你可以通过winow.localStorage 对象来访问HTML5 本地存储功能. 当然,考虑到浏览器兼容性,你在使用前应该先侦测一下你的用户的浏览器是否支持.
[html]  view plain  copy
  1. function supports_html5_storage() {  
  2.   try {  
  3.     return 'localStorage' in window && window['localStorage'] !== null;  
  4.   } catch (e) {  
  5.     return false;  
  6.   }  
  7. }  




另一种方式是使用 Modernizr  (译者:一个开源的用来侦测用户浏览器对HTML5支持度的工具) 来侦测
[html]  view plain  copy
  1. if (Modernizr.localstorage) {  
  2.   // window.localStorage is available!  
  3. } else {  
  4.   // 浏览器不支持HTML5 storage :(  
  5.   // 可以考虑使用dojox.storage 或其他方法  
  6. }  





如何使用HTML5 存储


HTML5 存储是基于键值对的。数据存储在一个键里,访问数据时可以根据同样的键获得上次存储的数据. 键是一个字符串. 而数据则可以是任何类型的JavaScript基本数据类型,包括 字符串,Boolean,整数,和浮点数. 不过需要注意的是,这些数据在存储时实际上是以字符串保存的。 因此在访问数据时你需要利用parseInt() 或 parseFloat()方法来做数据类型的转换。

[html]  view plain  copy
  1. interface Storage {  
  2.   getter any getItem(in DOMString key);  
  3.   setter creator void setItem(in DOMString key, in any data);  
  4. };  


如果在调用setItem 时使用一个已经存在的键,将会直接覆盖掉该键上保存的值。而调用getItem时传入一个不存在的键,则会返回一个null ,不会抛出异常。


就像其他JavaScript对象一样,你也可以将localStorage对象当成是关联数组使用(associative map) 

除了使用getItem和setItem之外,你可以使用中括号的方式来引用数据. 例如


[html]  view plain  copy
  1. var foo = localStorage.getItem("bar");  
  2. // ...  
  3. localStorage.setItem("bar", foo);  
  4. //和下面代码是等价的:  
  5. var foo = localStorage["bar"];  
  6. // ...  
  7. localStorage["bar"] = foo;  



该接口还提供了方法来删除某个键和清空整个存储区域(删除所有的键和值)

[html]  view plain  copy
  1. interface Storage {  
  2.   deleter void removeItem(in DOMString key);  
  3.   void clear();  
  4. };  


如果removeItem传入一个不存在的key则无操作,也不会有异常。 


最后,还提供了一个length属性来指示存储区域中所包含的所有键值对的数量 以及遍历所有键的key方法

[html]  view plain  copy
  1. interface Storage {  
  2.   readonly attribute unsigned long length;  
  3.   getter DOMString key(in unsigned long index);  
  4. };  


如果你向key方法传入了一个越界的值(不在0到length-1 之间),则该方法返回null。


翻译的第二部分已经发布:

HTML5 Local Storage( 本地存储) 的前世今生 (二)



HTML5本地存储(Local Storage) 的前世今生(二)

原文连接:http://diveintohtml5.org/storage.html (深入HTML5)
作者:Mark Pilgrim

译者 : feijia (tiimfei@gmail.com)


这篇文章是作者的书HTML5 up & Running的的一个章节,并在线以 CC-BY-3.0 License授权。

这是本文的第二部分,第一部分链接:

深入HTML5: HTML5 本地存储( Local Storage )的前世今生 (一)


追踪HTML5 存储区域中的数据变化


除了常用的存取数据的方法,开发者还需要能够侦测数据变化的编程接口。这就是存储事件(storage event )
当setItem(),removeItem()或者clear() 方法被调用,并且数据真的发生了改变时,storage事件就会被触发。注意这里的的条件是数据真的发生了变化。也就是说,如果当前的存储区域是空的,你再去调用clear()是不会触发事件的。或者你通过setItem()来设置一个与现有值相同的值,事件也是不会触发的。 

所有支持localStorage对象的浏览器都支持存储事件,也包括IE8。 不过由于IE8不支持W3C标准的addEventListener (IE9 支持)。因此要在不同浏览器中侦听存储事件,仍然需要一些代码来兼顾浏览器之间事件处理机制的不同。
当然你也可以使用jQuery,Dojo 或者其他Javacript类库来帮你注册事件处理函数,存储事件也是可以支持的。

[html]  view plain  copy
  1. if (window.addEventListener) {  
  2.   window.addEventListener("storage", handle_storage, false);  
  3. } else {  
  4.   window.attachEvent("onstorage", handle_storage);  
  5. };  


上面代码中handle_storage 是在存储事件发生时被调用的回调函数,传入参数是StorageEvent。 在IE中,该event对象会被保存在window.event 中。 

[html]  view plain  copy
  1. function handle_storage(e) {  
  2.   if (!e) { e = window.event; }  
  3. }  


StorageEvent对象会包含下列的属性。 
StorageEvent 对象
属性类型描述
keystring被修改的键。
oldValueany修改前的值(如果是增加新的键值,则该属性为null)
newValueany修改后的值(如果是删除键值,则该属性为null)
url*string触发当前存储事件的页面的url
* 注意: url 属性早期的规范中为uri属性。有些浏览器发布较早,没有包含这一变更。为兼容性考虑,使用url属性前,你应该先检查它是否存在,如果没有url属性,则应该使用uri属性

要注意一点,在存储事件的处理函数中是不能取消这个存储动作的。存储事件只是浏览器在数据变化发生之后给你的一个通知。

目前技术的局限


前面的章节中, 我提到了过去许多用来实现浏览器本地存储的技术和插件的缺点,例如存储容量的限制。其实HTML5本地存储标准也有它自身的局限。简单来说就是这几个关键词,“5M容量"和 “QUOTA_EXCEEDED_ERR“ 。

“5M容量",是每个来源(origin)(http://www.whatwg.org/specs/web-apps/current-work/multipage/origin-0.html#origin-0)允许存储容量的默认限制。在HTML5 存储标准中,5M只不过是作为一个建议的数值出现的,但是这个建议被所有的浏览器所采用。挺奇怪的,不是吗?  需要注意的是,存储的数据都是以字符串形式保存的。因此如果你存储了大量整型数或浮点数,这些数也会以字符串形式保存。浮点数的每一位都需要一个字符来表示。 这大大增加了所需要的存储空间。 

第二个关键词“QUOTA_EXCEEDED_ERR” 是一个异常,如果你使用的存储容量超过了5M,你就会碰到它。 

接下来你自然会要问那如果我想使用超过5M的容量,是不是可以通过弹出对话框让用户授权的方式来增加允许容量么?很遗憾,答案是”不行!“ 在这篇文章写作时,(2月 2011), 没有浏览器支持允许程序向用户请求更大存储空间的机制。  有些浏览器(例如Opera)允许用户自己来控制每个站点可使用的存储容量,但是这必须由用户自己主动发起才行,作为开发者你没有办法来发起这样的请求。 


HTML5 本地存储 实战


这一节让我们来实际操作一下HTML5 本地存储。 回忆一下我们在canvas章节中开发的Halma 游戏。由于没有加入本地存储支持,每次关闭浏览器这个游戏的进度就会丢失。现在我们可以用HTML5 本地存储技术在浏览器中保存玩家的游戏进度。这里是一个演示

试试看,在游戏中操作一些步骤,然后关闭该标签页然后在新标签页中再打开该游戏页面。如果你的浏览器支持HTML5本地存储,你会发现关闭前的游戏进度和状态被神奇的记录下来了。 


这是怎么实现的呢? 在游戏中,每次发生状态变化,我们都会调用下面的方法: 

[html]  view plain  copy
  1. function saveGameState() {  
  2.    if (!supportsLocalStorage()) { return false; }  
  3.    localStorage["halma.game.in.progress"] = gGameInProgress;  
  4.    for (var i = 0; i < kNumPieces; i++) {  
  5.    localStorage["halma.piece." + i + ".row"] = gPieces[i].row;  
  6.    localStorage["halma.piece." + i + ".column"] = gPieces[i].column;  
  7.    }  
  8.    localStorage["halma.selectedpiece"] = gSelectedPieceIndex;  
  9.    localStorage["halma.selectedpiecehasmoved"] = gSelectedPieceHasMoved;  
  10.    localStorage["halma.movecount"] = gMoveCount;  
  11.    return true;  


首先保存一个标志变量”gGameInProgress"用来指示当前是否有一个游戏正在进行。 然后是保存正在进行中的游戏的状态,包括哪些棋子被选中了,当前一共走的总步数等等 。 

在每次页面加载时,我们会调用resumeGame()方法,这个方法会先检查本地存储中的halma.game.in.progress"标志,如果是true,则会恢复上次保存的游戏状态。如果false,则调用newGame开始新游戏。 

[html]  view plain  copy
  1. function resumeGame() {  
  2.     if (!supportsLocalStorage()) { return false; }  
  3.     gGameInProgress = (localStorage["halma.game.in.progress"] == "true");  
  4.     if (!gGameInProgress) { return false; }  
  5.     gPieces = new Array(kNumPieces);  
  6.     for (var i = 0; i < kNumPieces; i++) {  
  7.     var row = parseInt(localStorage["halma.piece." + i + ".row"]);  
  8.     var column = parseInt(localStorage["halma.piece." + i + ".column"]);  
  9.     gPieces[i] = new Cell(row, column);  
  10.     }  
  11.     gNumPieces = kNumPieces;  
  12.     gSelectedPieceIndex = parseInt(localStorage["halma.selectedpiece"]);  
  13.     gSelectedPieceHasMoved = localStorage["halma.selectedpiecehasmoved"] == "true";  
  14.     gMoveCount = parseInt(localStorage["halma.movecount"]);  
  15.     drawBoard();  
  16.     return true;  
  17. }  


在上面resumeGame中最重要的一点就是“ 所有HTML5 本地存储中的数据都是以字符串形式保存的,如果你保存了其他数据类型,在访问这些数据时一定要自己对这些数据做强制类型转换"。 例如我们保存的标志变量gGameInProgress是一个Boolean类型。 在saveGameState()中我们不需要做任何特别操作
[html]  view plain  copy
  1. localStorage["halma.game.in.progress"] = gGameInProgress;  

但是在resumeGame中,我们要访问这个数据时,则必须做从string到Boolean的强制转换
[html]  view plain  copy
  1. gGameInProgress = (localStorage["halma.game.in.progress"] == "true");  

类似的,处理数值类型,例如gMoveCount 变量,在saveGameStat中我们用下面的语句保存一个整型变量
[html]  view plain  copy
  1. localStorage["halma.movecount"] = gMoveCount;  

但在resumeGame方法中,则要使用JavaScript的parseInt函数来将这个值从字符串转换为整型
[html]  view plain  copy
  1. MoveCount = parseInt(localStorage["halma.movecount"]);  

比键值对更强大的未来

相比HTML5标准成型前的混乱状态,今天HTML5本地存储的情形前所未有的令人振奋。 新的API被标准化,并且被所有的主流浏览器平台和设备所支持。 作为看惯了各种不兼容的Web程序员,很少有机会看到如此美妙一致的现实。 不过5M的存储容量以及仅仅能存储键值对这种简单数据结构对于较复杂的应用来说仍然是远远不够的。所以客户端持久化的未来仍然有许多发展的空间。而现在我们已经能看到许多互相竞争的技术在浮现。 


其中一种技术的大名你也许早就听到过 "SQL". (译者: 这句笑话很冷啊) 2007年,Google发布Gears项目。Gears是一个跨浏览器的插件,其中就包含了一个基于SQLite的嵌入式数据库。 这一早期原型后来影响了 Web SQL DataBase 规范 的建立. 
WebSQLDataBase (之前也称作 WebDB) 在SQL DB之上提供了一层简单封装,从而允许你在JavaScript中使用下面的代码: 

(这可不是伪代码,下面的代码在4个浏览器里是真的可以工作的!)


[html]  view plain  copy
  1. openDatabase('documents', '1.0', 'Local document storage', 5*1024*1024, function (db) {  
  2.   db.changeVersion('', '1.0', function (t) {  
  3.     t.executeSql('CREATE TABLE docids (id, name)');  
  4.   }, error);  
  5. });  


这段代码的核心就是传入 executeSql方法的SQL 语句。这里它能够支持所有的SQL语句,包括SELECTUPDATE, INSERT 和 DELETE。 一切都和后台的数据库编程没什么区别,唯一不同的是你是在JavaScript里调用的! 太欢乐了!

Web SQL Database 标准已经在4个浏览器(以及对应的平台)中被实现了。

Web SQL Database supportIE    Firefox    Safari    Chrome    Opera    iPhone    Android
·    ·    4.0+    4.0+    10.5+    3.0+    2.0+

当然,如果你对SQL略微有所了解的话,你就会明白其实“SQL” 这个词更多只是一个常用术语而不是一个真正统一的标准。( 这其实和HTML5 这个词是一样的 ) 当然,我们读书时都学过一个SQL-92 标准,遗憾的是在现实世界里,没有一款产品能真正的严格符合这套标准。因此我们知道有甲骨文的SQL,微软的SQL,MySQL的SQL, PostgreSQL的SQL, SQLite的SQL。 每个厂商都在自己的数据库产品中加入了特有的SQL新特性。甚至在一个厂商的产品中,不同的版本间SQL的用法也会产生变化。


这些SQL业界的纷争就导致了我们看到在Web SQL Database 规范中出现了如下的免责声明:

本规范现在碰到了一个难题: 所有的感兴趣的厂商目前都使用了同样的SQL后台(Sqllite), 但是我们还需要有更多独立的实现来使本规范成为一个标准。目前本规范中所使用的SQL语法(SQL dialect)只是一个基于Sqlite所支持的SQL语法的参考,并不会作为将来标准的一部分。 

另一个与此竞争的技术是  索引数据库(Indexed Database API ) , 之前也称作WebSimpleDB, 不过现在更多人叫它IndexedDB


索引数据库API主要的概念是对象存储容器(object store),对象存储容器很像SQL中的数据库概念。每个数据库(object store)中都有很多记录(对象),每个记录都有很多字段(fields)。每个字段都有其预定义好的数据类型。 你可以选择所有记录的子集,使用游标来遍历所有记录, 也提供了事务的概念来保证数据完整性和一致性。 

所有这些概念都和传统SQL数据库编程很相似。最主要的区别在于,Object Store之上不能使用SQL语句这种结构化的查询语言。 你用不着构建像SELECT * from USERS where ACTIVE = 'Y' 这样的查询。 你要做的是通过object store 提供的方法在名为USERS的数据库上打开一个游标指针(cursor)来遍历所有记录,然后过滤掉那些不满足条件的记录,最后在剩下的记录上使用数据访问方法获取你所需要的数据。 这篇 索引数据库入门 是一篇很好的教程,里面 详细比较了索引数据库和Web SQL 数据库

在本文写作时,索引数据库只是在FF4 的beta版中被实现了。 Mozilla已经声明他们 永远不会去实现Web SQL 数据库 . Google 则说他们 正考虑在Chromium和Google Chrome上支持索引数据库
连微软也说索引数据库是" 很好互联网解决方案 "

那么你究竟能用索引数据库干点什么呢? 在目前的状况下,除了一些演示之外几乎什么也做不了。 但是谁知道1年之后会不会就大不一样了呢。  请参考  深入阅读  一节的资料和教程。


深入阅读


HTML5 存储规范 

DOM存储简介  , MSDN 

Web Storage: easier, more powerful client-side data storage , Opera Developer Community   

DOM 存储 ,  Mozilla developer Center(注意: 这篇文章大部分是介绍FF的globalStorage对象的实现。该对象是在标准的localStorage对象出现前的原型。在FF3.5之后,Mozilla加入了对标准localStorage接口的支持)

Unlock local storage for mobile Web applications with HTML5 , a tutorial on IBM DeveloperWorks


 Brad Neuberg 在HTML5 规范出现前的一些工作

Web SQL Database:

IndexedDB:







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值