常用缓存方式:

一、cookie

  Cookie(或者Cookies),指一般网站为了辨别用户身份、进行session跟踪而存储在用户本地终端上的数据(通常经过加密)。cookie一般通过http请求中在头部一起发送到服务器端。一条cookie记录主要由键、值、域、过期时间、大小组成,一般用户保存用户的认证信息。cookie最大长度和域名的个数由不同浏览器决定,具体如下:

浏览器

支持域名个数

最大长度

IE7以上

50个

4095B

Firefox

50个

4097B

Opera

30个

4096B

Safari/WebKit

无限制

4097B

  不同域名之间的cookie信息是独立的,如果需要设置共享可以在服务器设置cookie的path和domain来实现共享。浏览器端也可以通过document.coolie来获取cookie,并通过js浏览器端也可以方便的读取、设置cookie的值。

 

  1:cookie的几个字段代表什么(expires、domain、path、secure、HttpOnly):

    1)expries/max-age:设置cookie的有效时间,也就是过期时间,默认为本次会话即关闭后消失

        expires是http/1.0协议中的,在新的http/1.1协议中由max-age替代

        expires是过期时间点,必须为GMT格式的时间(可用new Date().toGMTString()或new Date().toTCSSring()来获得)

        max-age是时间段,以秒为单位,即失效时刻 = 创建时刻 + max-age

    2)domain、path:域名,两者构成URL,共同限制cookie被哪些URL访问

        若domain=“baidu.com”,path=“/”,则请求资源(不包括XHR资源)时,只要URL为“baidu.com”的域名或子域名,且路径为“/”或子目录,请求头中都会带cookie信息

    3)secure:只在确保安全的请求中才会发送cookie,即https或者其他安全协议下,默认情况下secure为空

    4)httponly:设置cookie是否能通过js进行访问,js无法设置该选线,由服务器端设置,默认情况下httponly为空

  

  2:简单说了下cookie,接下来然我们探讨一下几个问题:()

    1)cookie应存储什么数据

    2)cookie怎么设置 

    3)cookie为什么会自动添加到http请求的request header中

    4)cookie增删改查

  3:设置cookie:使用document.cookie,如果不赋值的话,是获取cookie的值(key和value),赋值的话是设置cookie

      expires的设置是GMT时间,domain设置是本域名下(在https://www.baidu.com下domain可以设置为.baidu.com),path设置一般为/即可,secure设置写上即可

document.cookie = "age=123; expires=Sun, 01 Jan 2017 00:00:00 GMT; domain=.google.co.jp; paht=/"

  4:修改cookie:重新复制即可,但保证domain/path与之前的保持一致,否则会重新创建cookie

  5:删除cookie:重新设置cookie的过期时间即可,设置过去的时间,比如今天为2016-10-01,设置cookie的过期时间为2016-10-01之前就行

  注:cookie个别参考文档:http://bubkoo.com/2014/04/21/http-cookies-explained/

    https://github.com/component/cookie/blob/master/index.js

 

二、localStorage

  localStorage是html5的一种新的本地缓存方案,目前用的比较多,一般用来存储ajax返回的数据,加快下次页面打开时的渲染速度。

浏览器

最大长度

IE9以上

5M

Firefox 8以上

5.24M

Opera

2M

Safari/WebKit

2.6M

  值得注意的是,localstorage大小有限制,不适合存放过多的数据,如果数据存放超过最大限制会报错,并移除最先保存的数据。

  1:localStorage作为浏览器的一种缓存方式,其存储数据的方式为key-value键值对的方式存在

  2:localStorage语法API

  

1 var ls = window.localStorage;
2 ls.setItem(key,value);//设置key-value,存储数据
3 ls.getItem(key);//获取key对应的value值,没有返回null
4 ls.length;//只读属性,用来获取存储总数
5 ls.key(index);//获取index位置上的key值
6 ls.removeItem(key);//移除该key值的整条数据
7 ls.clear();//清除所有的存储数据

 

  注:https://github.com/machao/localStorage

 

三、sessionStorage

  sessionStorage和localStorage类似,localStorage是永久存储,sessionStorage是本次会话存储,其它均类似。

 

四、websql

 

  • Web Sql数据库API实际上不是HTML5规范的组成部分;
  • 在HTML5之前就已经存在,是单独的规范;
  • 它是将数据以数据库的形式存储在客户端,根据需求去读取;
  • 跟Storage的区别是:Storage和Cookie都是以键值对的形式存在;
  • Web Sql更方便与检索,允许sql语句查询;
  • 让浏览器实现小型数据库存储功能;
  • 这个数据库是集成在浏览器里面的,目前主流浏览器基本都支持;

  websql API主要包含三个核心方法:

  • openDatabase : 这个方法使用现有数据库或创建新数据库创建数据库对象。
  • transaction : 这个方法允许我们根据情况控制事务提交或回滚。
  • executeSql : 这个方法用于执行真实的SQL查询。
1 var db = openDatabase('DBname','1.0','DB描述',2*1024)
2         //openDatabasek中五个参数分别为:数据库名、版本号、描述、数据库大小、创建回调。创建回调没有也可以创建数据库。
3 db.transaction(function(tx){
4    tx.executeSql('SQL语句',['用于替代sql语句中?'],function(s,c){
5         //用于处理查询语句查询到的结果
6     })
7 })

注:简单sql语句—http://www.uml.org.cn/sjjm/201005132.asp

    (insert into /// select * from xxxx)

五、indexDB

IndexDB是一个为了能够在客户端存储可观数量的结构化数据,并且在这些数据上使用索引进行高性能检索API。虽然DOM存储对于少量数据是非常有用的,但是他对大量结构化数据的存储就显得力不存心了。IndexDB则提供了这样的一个解决方案。IndexDB分别为同步和异步访问提供单独的API。同步API本来是要用于仅供Web Workers内部使用,但是还没有被任何浏览器所实现。异步API在Web Workers内部和外部都可以使用,另外浏览器可能对IndexDB有50M大小的限制,一般用户保存大量用户数据并要求数据之间有搜索需要的场景。

  1、异步API

  • indexedDB.open:该方法接收两个参数,第一个为打开或新建的数据库名称(不可省略),第二个参数为版本(大于0的正整数,如果忽略该参数,默认为1);返回IDBOpenDBRequest对象,回调函数定义在该对象上面,回调函数接收一个event作为参数,e.target.result属性就指向打开的indexedDB数据库
      打开/新建数据库为异步操作,有时隔事件可能触发:
  • success:打开成功。
  • error:打开失败。
  • upgradeneeded:第一次打开该数据库,或者数据库版本发生变化。
  • blocked:上一次的数据库连接还未关闭。
  • indexedDB实例对象的方法
  • createObjectStore:该方法为创建存放数据的“对象仓库”需要放在upgradeneeded事件中执行,它接收两个参数,第一个参数为存放数据的对象仓库的名称,第二个参数是一个对象是设置对象仓库的属性(例{keyPath:‘name’},将name作为键名,键名不可重复;{autoIncrement:true}是否使用自动递增的整数作为键名);注:创建对象仓库时,如果已存在,会报错。
  • objectStoreNames:该属性返回一个DOMStringList对象,包含所有对象仓库名称,可以使用该对象的contains方法判断是否包含某个对象仓库。(先判断是否存在,在绝对是否创建)
  • transaction:该方法用于创建一个数据库事务,对数据库进行读写操作,必须先创建数据库事务。
      该方法接收两个参数,第一个参数为数组,数组中是本次操作所涉及的对象仓库,第二个参数是表示操作类型的字符串“readonly”(只读)和readwrite(读写)
      该方法返回一个事务对象,该对象的objectStore方法用于获取指定的对象仓库
      该方法有三个事件,可用来定义回调函数
  • abort:事务中断。
  • complete:事务完成。
  • error:事务出错。
  •      事务对象有以下方法,用于操作数据
      • add:添加数据,两个参数,第一个为对象,即要添加的数据对象,第二个参数可选,对应的键名
      • get:读取数据,一个参数
      • put:更新数据,两个参数,和add一样
      • delete:删除数据,一个参数,指定键名
      • openCursor:遍历数据,异步方法,回调函数接收事件对象作为参数,该对象的target.result指向数据对象
  • createIndex:该方法用于创建索引,假设仓库中的数据对象为如下person类型:

  • var person = {
    name:name,
    email:email,
    created:new Date()
    }


  • 可以指定这个数据对象的某个属性来建立索引

  • var stor = db.createObjectStore('people',{autoIncrement:true});
    stor.createIndex('name','name',{unique:false});
    stor.createIndex('email','email',{unique:true});


     

  • createIndex方法接收三个参数,第一个为索引名称,第二个是建立索引的属性名,第三个为参数对象,用来设置索引特性。unique表示索引所在的属性是否有唯一值,上面代码表示name属性不是唯一值,email属性是为一值。
  • index:有了索引之后就可以针对索引所在的属性读取数据。index方法用于从对象仓库返回指定的索引。

  • var t = db.transaction(['people'],'readonly');
    var stor = t.objectStore('people');
    var index = store.index('name');
    var request = index.get(name);


     

  • 上面代码打开对象仓库之后,先用index方法指定索引在name属性上,然后用get方法读取某个name属性所在数据。如果没有指定索引的那一行代码,get方法只能按照键名读取数据,而不是按照name属性读取数据。需要注意的是,这时get方法有可能取回多个数据对象,以为name属性没有唯一值。另外get是异步方法,读取成功后,只能在success事件的回调中处理数据。
  • IDBKeyRange对象
    索引的有用之处,还在于可以指定读取数据的范围。这需要用到浏览器原生的IDBKeyRange对象。
    IDBKeyRange对象的作用是生成一个表示范围的Range对象。生成方式有四种:
    • lowerBound方法:指定范围上限
    • upperBound方法:指定范围上限
    • bound方法:指定范围上下限
    • only方法:指定范围中只有一个值

    • //  all keys <= x
      var r1 = IDBKeyRange.upperBound(x);
      
      //  all keys < x
      var r2 = IDBKeyRange.upperBound(x,true);
      
      //  all keys >= y
      var r3 = IDBKeyRange.lowerBound(y);
      
      //  all keys > y
      var r4 = IDBKeyRange.lowerBound(y,true);
      
      //  all keys >= x && keys <=y
      var r5 = IDBKeyRange.bound(x,y);
      
      //  all keys > x && keys <y
      var r6 = IDBKeyRange.bound(x,y,true,true);
      
      //  all keys = z
      var r7 = IDBKeyRange.only(z);


       

    • 前三个方法(lowerBound、upperBound、bound)默认包括端点值,可以传入一个布尔值,修改这个属性。
      生成Range对象之后,将他们作为参数输入openCursor方法,就可以在所设定的范围内读取数据

    • var t = db.transaction(['people'],'readonly');
      var store =t.objectStore('people');
      var index = store.index('name');
      
      var range = IDBKeyRange.bound('B','D');
      index.openCursor(range).onsuccess = function(e){
         var cursor = e.target.result;
         if(cursor){
            console.log(cursor.key + ":")  
            for(var field in cursor.value){
                console.log(cursor.value[field]);
            }
             cursor.continue();//将指针指向下一个数据,如果已经是最后一个了,则指向null
          }     
      }


  注:参考教程http://javascript.ruanyifeng.com/bom/indexeddb.html

基本淘汰以及兼容性较差的几种缓存方式

一、flash缓存

二、HTTP缓存

三、application cache

四、cacheStorage