html5 本地存储-sessionStorage localStorage 本地数据库

Html5支持两种的WebStorage,一种是永久性的本地存储(localStorage),另外一种是会话级别的本地存储(sessionStorage) 。

特性 Cookie localStorage sessionStorage
数据的生命期 可设置失效时间,默认是关闭浏览器后失效 除非被清除,否则永久保存 仅在当前会话下有效,关闭页面或浏览器后被清除
存放数据大小 4K左右 一般为5MB 一般为5MB
与服务器端通信 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题 仅在客户端(即浏览器)中保存,不参与和服务器的通信 仅在客户端(即浏览器)中保存,不参与和服务器的通信
易用性 需要程序员自己封装,源生的Cookie接口不友好 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持 源生接口可以接受,亦可再次封装来对Object和Array有更好的支持

HTML5 LocalStorage 本地存储

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

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

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

 

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



支持的情况如上图, IE 8.0 的时候就支持了,非常出人意料。不过需要注意的是, IE Firefox 测试的时候需要把文件上传到服务器上(或者 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"/>



会话级别的本地存储:sessionStorage


sessionStorage与localStorage用法一样
唯一区别: 前者关闭浏览器后自动清空,后者永久保存

在Html5中增加了一个Js对象:sessionStorage;通过此对象可以直接操作存储在浏览器中的会话级别的WebStorage。存储在sessionStorage中的数据首先是Key-Value形式的,另外就是它跟浏览器当前会话相关,当会话结束后,数据会自动清除,跟未设置过期时间的Cookie类似。

sessionStorage提供了四个方法来辅助我们进行对本地存储做相关操作。

!!window.sessionStorage;  检查浏览器是否支持

  • (1)setItem(key,value):添加本地存储数据。两个参数,非常简单就不说了。
  • (2)getItem(key):通过key获取相应的Value。
  • (3)removeItem(key):通过key删除本地数据。
  • (4)clear():清空数据。

    <script type="text/javascript">
        //添加key-value 数据到 sessionStorage
	sessionStorage.setItem("demokey", "http://blog.itjeek.com");
        //通过key来获取value
        var dt = sessionStorage.getItem("demokey");
        alert(dt);
        //清空所有的key-value数据。
        //sessionStorage.clear();
        alert(sessionStorage.length);
    </script>



Database Storage

对简单的数据存储,使用sessionStoragelocalStorage能够很好地完成,但是在对琐碎的关系数据进行处理之外,它就力所不及了。而这正是 HTML 5 Web SQL Database”API 接口的应用所在。

A、打开链接

 var db = openDatabase("ToDo""0.1""A lalert of to do items.", 200000);    // 打开链接    

 if(!db) { alert("Failed to connect to database."); }                         // 检测连接是否创建成功    

1.	var db = openDatabase("ToDo", "0.1", "A lalert of to do items.", 200000);    // 打开链接  
2.	if(!db) { alert("Failed to connect to database."); }                         // 检测连接是否创建成功  


以上代码创建了一个数据库对象 db,名称是 Todo,版本编号为0.1db 还带有描述信息和大概的大小值。如果需要,这个大小是可以改变的,所以没有必要预先假设允许用户使用多少空间。

绝不可以假设该连接已经成功建立,即使过去对于某个用户它是成功的。为什么一个连接会失败,存在多个原因。也许用户代理出于安全原因拒绝你的访问,也许设备存储有限。面对活跃而快速进化的潜在用户代理,对用户的机器、软件及其能力作出假设是非常不明智的行为。比如,当用户使用手持设备时,他们可自由处置的数据可能只有几兆字节。

B、执行查询

db.transaction( function(tx) {     

 tx.executeSql(    
 "INSERT INTO ToDo (label, timestamp) values(?, ?)",     
 ['lebel'new Date().getTime()],     
 function(tx2, result){ alert('成功'); },     
function(tx2, error){ alert('失败:' + error.message); }    
  );     
  });     
1.	db.transaction( function(tx) {   
2.	    tx.executeSql(  
3.	        "INSERT INTO ToDo (label, timestamp) values(?, ?)",   
4.	        ['lebel', new Date().getTime()],   
5.	        function(tx2, result){ alert('成功'); },   
6.	        function(tx2, error){ alert('失败:' + error.message); }  
7.	    );   
8.	});   


  1. 执行SQL语句使用database.transaction()函数,该函数只有一个参数,负责执行查询的函数。
  2. 该函数具有一个类型事务的参数(tx)。
  3. 该事务参数(tx)具有一个函数:executeSql()。这个函数使用四个参数:
    表示查询的SQL字符串;插入到查询中问号所在处的字符串数据;一个成功时执行的函数;一个失败时执行的函数。
  4. 执行成功的函数有两个参数:tx2,事务性参数;result,执行的返回结果,结构如图
  5. 执行成功的函数也有两个参数:tx2,事务性参数;error,错误对象,结构如图 

C、其它

  • Chrome支持; firefox(测试时版本4.01)不支持;IE8不支持。

D、示例

 //创建数据库    

var db = openDatabase("users""1.0""用户表", 1024 * 1024);     
 if(!db){    
alert("Failed to connect to database.");     
  } else {    
  alert("connect to database 'K'.");     
 }          
 // 创建表    
db.transaction( function(tx) {     
   tx.executeSql(    
     "CREATE TABLE IF NOT EXISTS users (id REAL UNIQUE, name TEXT)",     
  [],     
  function(){ alert('创建users表成功'); },     
  function(tx, error){ alert('创建users表失败:' + error.message); }    
  );    
 });         
 // 插入数据    
 db.transaction(function(tx) {     
   tx.executeSql(    
   "INSERT INTO users (id, name) values(?, ?)",     
     [Math.random(), 'space'],     
     function(){ alert('插入数据成功'); },     
      function(tx, error){ alert('插入数据失败: ' + error.message);}    
     );     
 });     
   
// 查询    
db.transaction( function(tx) {     
    tx.executeSql(    
      "SELECT * FROM users", [],      
      function(tx, result) {    
         var rows = result.rows, length = rows.length, i=0;    
        for(i; i < length; i++) {     
         alert(    
              'id=' + rows.item(i)['id'] +     
           'name='+ rows.item(i)['name']    
      );     
   }     
 },     
      function(tx, error){    
         alert('Select Failed: ' + error.message);    
   }    
   );     
 });     
     
// 删除表    
 db.transaction(function (tx) {      
   tx.executeSql('DROP TABLE users');     
 });   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值