Web Storage API : LocalStroage

这是一篇详细介绍详细介绍详细介绍_(:з」∠)_

 

背景:

当你访问一个页面,并不是丢到服务器,等待用户访问就可以了的。从输入网址到显示网页的全过程,可以参考这里

简单来说,在输入url按下回车键后,首先会进行浏览器查找域名的IP地址,然后浏览器给web服务器发送一个HTTP请求,这是如果浏览器有重定向会跟踪重定向地址。服务器“处理”请求,浏览器发送获取嵌入在HTML中的对象,浏览器开始显示HTML会注意到需要获取其他地址内容的标签。这时,浏览器会发送一个获取请求来重新获得这些文件。如以下几种文件:
* 图片
* CSS 式样表
* JavaScript 文件
这些地址都要经历一个和HTML读取类似的过程。所以浏览器会在DNS中查找这些域名,发送请求,重定向等等

这样会导致很多静态文件不断被请求,消耗资源。

 

目的:

因为请求多,所以如果每次用户访问页面都要加载,会很影响性能,很浪费带宽。

这时,与动态页面不同的是,静态文件会允许浏览器对其进行缓存。有的文件可能会不需要与服务器通讯,而从缓存中直接读取。服务器的响应中包含了静态文件保存的期限信息,所以浏览器知道要把它们缓存多长时间。还有,每个响应都可能包含像版本号一样工作的ETag头(被请求变量的实体值),如果浏览器观察到文件的版本 ETag信息已经存在,就马上停止这个文件的传输。所以我们可以利用304,让浏览器使用本地缓存。

 

解决方案:

一:关于存储你需要了解的:

  1、存储的历史:

  引用自:http://www.cnblogs.com/xiaowei0705/archive/2011/04/19/2021372.html 博客的图片

  

最早的Cookies,大概4KB只支持每个域名20cookiesuserData是IE的。Flash空间是Cookie的25倍。再之后Google推出了Gears,虽然没有限制,但要装额外的插件(没具体研究过)。到了HTML5把这些都统一了,官方建议是每个网站5MB,就存些字符串,这篇文章的重点也在如何使用这5M存储上。Html5支持两种的WebStorage,一种是永久性的本地存储(localStorage),另外一种是会话级别的本地存储(sessionStorage)。

  2、H5里的存储方案

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

虽然Html5已经提供了功能强大的localStorage和sessionStorage,但是他们两个都只能提供存储简单数据结构的数据,对于复杂的Web应用的数据却无能为力。逆天的是Html5提供了一个浏览器端的数据库支持,允许我们直接通JS的API在浏览器端创建一个本地的数据库,而且支持标准的SQL的CRUD操作,让离线的Web应用更加方便的存储结构化的数据。接下里介绍一下本地数据的相关API和用法。

(摘自:http://www.cnblogs.com/fly_dragon/p/3946012.html)

  sessionStorage和localStorage最大的区别就是,一个是会话级别的,localstorage是永久本地保存的。

  而本地数据库与前面两者不同在于,前面两者只能提供存储简单数据结构的数据,对于复杂的Web应用的数据却无能为力。但在Html5里提供了一个浏览器端的数据库支持,允许我们直接通JS的API在浏览器端创建一个本地的数据库,而且支持标准的SQL的CRUD操作,让离线的Web应用更加方便的存储结构化的数据。

  3、localstroage本身

  本着提[yi]供[lian]最[zheng]原[jing]汁[de]原[hu]味[shuo]的[ba]口[dao]感,找了Web APIs | MDN上的介绍是长这样的:

The localStorage property allows you to access a local Storage object. localStorage is similar to sessionStorage.

The only difference is that, while data stored in localStorage has no expiration time, data stored in sessionStorage gets cleared when the browsing session ends—that is, when the browser is closed.

翻译:localStorage属性允许您访问本地存储对象。localStorage类似sessionStorage。

唯一不同的是,存储在本地存储的数据没有过期时间,存储在sessionStorage的数据会在浏览会话结束时清除,就是当浏览器关闭时。

原理:

Web Storage 包含如下两种机制:

  • sessionStorage 为每一个给定的源(given origin)维持一个独立的存储区域,该存储区域在页面会话期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)。
  • localStorage 同样的功能,但是数据保存在电脑本地,所以当浏览器关闭后,重新打开后数据仍然存在。

这两种机制是通过 Window.sessionStorage 和 Window.localStorage 属性使用(to be more precise, in supporting browsers the Window object implements the WindowLocalStorage and WindowSessionStorage objects, which the localStorage and sessionStorage properties hang off)—— 调用其中任一对象会创建 Storage 对象,通过 Storage 对象,可以设置、获取和移除数据项。对于每个源(origin)sessionStorage 和localStorage 使用不同的 Storage 对象——独立运行和控制。

例如,在文档中调用 localStorage 将会返回一个 Storage 对象;调用 sessionStorage 返回一个不同的 Storage 对象。可以使用相同的方式操作这些对象,但是操作是独立的。

 

二:应该怎样使用?

1、对于localStorage和sessionStroage来说,可以这样存入

//如果是session就把前面改为sessionStorage
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的值

 

 

存储后:

可以遍历

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);
}

可以封装

使用 JSON.stringify 和 JSON.parse 封装数据

var data = {};  
data['name'] = name;  
data['gender'] = gender;  
localStorage.setItem(
'data', JSON.stringify(data)); var data = JSON.parse(localStorage.getItem('data')); //stringify()用于从一个对象解析出字符串 var a = {a:1,b:2} JSON.stringify(a); "{"a":1,"b":2}" //parse用于从一个字符串中解析出json对象 var str = '{"name":"huangxiaojian","age":"23"}' JSON.parse(str); age: "23" name: "huangxiaojian" __proto__: Object

可以监听

// 监听数据变化,当数据发生变化时,同步数据显示  
window.onstorage = function(event){  
    var status = {}  
    status.key = event.key;  
    status.oldValue = event.oldValue;  
    status.newValue = event.newValue;  
    status.url = event.url;  
    status.storage = event.storageArea;  
  
    // 执行同步数据处理...  
}  

 通过 StorageEvent 响应存储的变化

无论何时,Storage 对象发生变化时(即创建/更新/删除数据项时,重复设置相同的键值不会触发该事件,Storage.clear() 方法至多触发一次该事件),StorageEvent 事件会触发。在同一个页面内发生的改变不会起作用——在相同域名下的其他页面(如一个新标签或 iframe)发生的改变才会起作用。在其他域名下的页面不能访问相同的 Storage 对象。

在事件结果页面中的 JavaScript 如下所示(可见 events.js):

window.addEventListener('storage', function(e) {  
  document.querySelector('.my-key').textContent = e.key;
  document.querySelector('.my-old').textContent = e.oldValue;
  document.querySelector('.my-new').textContent = e.newValue;
  document.querySelector('.my-url').textContent = e.url;
  document.querySelector('.my-storage').textContent = e.storageArea;
});

这里,我们为 window 对象添加了一个事件监听器,在当前域名相关的 Storage 对象发生改变时该事件监听器会触发。正如你在上面看到的,此事件相关的事件对象有多个属性包含了有用的信息——改变的数据项的键,改变前的旧值,改变后的新值,改变的存储对象所在的文档的 URL,以及存储对象本身。

 

2、操作本地数据库的最基本的步骤是:

(1)第一步:openDatabase创建一个访问数据库的对象

//Demo:获取或者创建一个数据库,如果数据库不存在那么创建之
var dataBase = openDatabase("student", "1.0", "学生表", 1024 * 1024, function () { });

(2)第二步:

db.transaction方法可以设置一个回调函数,此函数可以接受一个参数就是我们开启的事务的对象。然后通过此对象可以进行执行Sql脚本,跟下面的步骤可以结合起来。使用第一步创建的数据库访问对象来执行transaction方法,通过此方法可以设置一个开启事务成功的事件响应方法,在事件响应方法中可以执行SQL.

(3)第三步:通过executeSql方法执行查询,当然查询可以是:CRUD

ts.executeSql(sqlQuery,[value1,value2..],dataHandler,errorHandler)

 

 

 

三:存进去之后?

  我们来思考几个问题,这些数据会存到哪里?怎样存进去的?什么时候存满?怎样算存满?存满之后会发生什么又要怎样解决?

  1、sessionStorage

  先从简单的开始~既然是session作为会话级别的存储,

  (0)它均只能存储字符串类型的对象

  (1)各浏览器支持的 localStorage 和 sessionStorage 容量上限不同。一般大约在5M左右,有兴趣的同学可以来玩测试页面(记得FQ

  (2)存进去的数据在关闭浏览器后就会自动销毁,可以用来保存一些不希望被保存在浏览器里的个人信息,这样在关闭掉浏览器后就可以删掉。

  (3)它还有一种用法,用sessionStorage来判断页面是关闭还是刷新

  2、localStorage

  (0)Chrome 的存储方式是以sqlite的数据库文件形式存储。C:\Users\Username\AppData\Local\Google\Chrome\User Data\Default\Local Storage

  (1)localStorage没有过期时间,只要不clear或remove,数据会一直保存。

  (2)localStorage 是以key-value形式保存数据的,key和value只能是字符串格式。因此数字1保存后,会转换成字符串1。

  (3)本来是设计用来存储数据,但可以做静态资源可编程缓存。可用于开发移动端单页面应用(也有叫webapp)。具体看看这篇知乎上的运用

      静态资源(JS/CSS)存储在localStorage有什么缺点?为什么没有被广泛应用?

  (4)localStorage 默认支持的容量为一个站5M,当调用setItem超过上限时,会触发QuotaExceededError异常。当然有些浏览器支持修改容量上限,但为了兼容其他浏览器,最好按5M的容量来使用。特例有两个chrome molie是2M多的版本……(也就是说整个浏览器加起来不止5M,具体多少可以到c盘看看~

  (5)当存满时,在某些情况下,用户可以自行调整:

    Opera: opera:配置为localStorage >域配额
    火狐:about:配置-> dom.storage.default_quota

    然而作为一个开发者来说,这是一种很不友好的用户体验,所有我们必须作出一些判断:

      存储的时候为每个key设置一个失效时间。

      if 当存满的时候,在存取时对localStorage的容量进行判断,浏览器检查是否有足够的剩余空间为当前域

        如果足够:

          数据存储,如果存在相同的键对它进行覆盖。

        如果不足:
          数据不存储。用js遍历key的失效时间,对达到失效时间的key和value值删除

          如果删除后仍然无法存储则抛出错误:

            一个quota_exceeded_err抛出异常。

            如opera它会显示一个对话框,让用户选择增加当前域的存储空间。

//设置expire
var obj = {data: value}
if (expire > 0) {
      obj.expire = Date.now() + expire * 1000;
}
setData = JSON.stringify(obj) || '';
localStorage.setItem(key, setData);
//失效删除
if (obj && obj.data) {
   if (!('expire' in obj) || obj.expire > Date.now()) {
       return obj.data;
    }
   this.remove(key);
}
//取数并判断是否有数,缺少值的删除
var obj;
      var value = localStorage.getItem(key);
      try {
        obj = JSON.parse(value);
      } catch (e) {
        obj = value;
      }
    if (obj && obj.data) {
      return {data: obj.data, expire: !(!('expire' in obj) || obj.expire > Date.now())};
    } else {
      return {data: null, expire: true};
    }

 

  3、本地数据库
  (0)Windows,Chrome的数据存储在”C:\Users\your-account-name\AppData\Local\Google\Chrome\User Data\Default\”下

     Firefox 的数据存储在”C:\Users\your-account-name\AppData\Local\Mozilla\Firefox\Profiles\”目录下。

  (1)对于web SQL更详细的文章https://www.ibm.com/developerworks/cn/web/1108_zhaifeng_websqldb/

 

参考文献:

https://www.zhihu.com/question/28467444

http://www.cnblogs.com/fly_dragon/p/3946012.html

https://www.zhihu.com/question/20790576/answer/32602154

https://www.zhihu.com/question/34873227/answer/68188730

https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

http://www.cnblogs.com/xiaowei0705/archive/2011/04/19/2021372.html

posted @ 2016-03-31 11:43  Coder豆腐  阅读(497)  评论(0编辑  收藏  举报