Local Storage :永久存储:数据将保持在硬盘中,即便浏览器被关闭了,该数据仍然存在,
下次打开浏览器访问该网站时仍然能够继续使用
Session Storage :临时存储:数据会随着浏览器的关闭而消失。
Indexed Database:NOSql,至关于一个key和value的集合,实现了NOSql的存储方式
Web SQL Database:实现了传统的基于sql语句的数据库操做,关系数据库 javascript
1)、带name的可用表单元素css
2)、urlhtml
3)、客户端请求头部信息java
4)、cookiejquery
顾名思义客户端本地存储就是将信息存储在客户端电脑上,cookie就是一种典型的传统客户端存储,长期以来本地存储能力一直是桌面应用区别于Web应用的一个主要优点,做为Web应用程序而言,新一代的HTML标准对数据的本地存储提出了更高的要求。传统的Web数据存储方式一直来使用的是Cookie,但Cookie有如下缺陷:git
a)、cookie会被附加在每一个HTTP请求中,因此无形中增长了流量。github
b)、因为在HTTP请求中的cookie是明文传递的,因此安全性成问题。sql
c)、Cookie的大小限制在4 KB左右,容量达不到要求。chrome
HTML5中的Web Storage,称为Web本地存储,在Web客户端储存数据的功能,用键值对的形式保存数据,曾经属于HTML5的规范,目前已经被独立出来造成单独的规范体系。本地存储优点:数据库
a)、统一的标准,兼容性高(IE八、各大浏览器支持)
b)、数据存储量大
c)、无需安装插件
d)、减小网络流量
e)、更加适合移动端
HTML5 提供了四种在客户端存储数据的新方法,即localStorage 、sessionStorage、globalStorage、Web Sql Database。 前面三个适用于存储较少的数据,而Web Sql Database适用于存储大型的,复杂的数据,我习惯把前面的三个称之为小存储。 IE八、Firefox3.六、Chrome五、Safari四、Opera10,事实证实各个浏览器在API方面的实现基本上一致,存在必定的兼容性问题,但不影响正常使用。
在chrome浏览器中可使用开发者工具查看到各类不一样的本地存储方式,以下图所示:
Web SQL Database 和 Indexed Database 都是在客户端存储大量结构化数据的解决方案。Web SQL Database 实现了传统的基于 SQL 语句的数据库操做,而 Indexed Database 实现了 NoSQL 的存储方式。
Web Storage 这种用于存储 (key, value),通常二者都是字符串;
IndexDB 是加强型的 Web Storage,也是存储 (key, value);
Web SQL 则是 SQLite,一个完整的关系型数据库,能够执行 SQL。
WebSQL是SQLite在浏览器中的实现,因此它是一种关系型数据库。因为W3C对其规范定义不够理想,各家浏览器有各自实现,有浏览器兼容问题;
IndexDB是一种key-value类型的非关系数据库(NoSQL)
https://github.com/js-cookie/js-cookie
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Cookie</title> </head> <body> <input type="button" name="add" id="add" value="添加" /> <input type="button" name="get" id="get" value="读取" /> <input type="button" name="remove" id="remove" value="清除" /> <script src="js/js.cookie-2.1.3.min.js" type="text/javascript" charset="utf-8"></script> <script src="../js/jquery-1.11.3.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $("#add").click(function(){ Cookies.set('name','小明',{expires:7}); }) $("#get").click(function(){ alert(Cookies.get('name')) }) $("#remove").click(function(){ Cookies.remove('name') }) </script> </body> </html>
结果:
添加的结果:
读取的结果:
清除的结果:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>本地永久存储:localStorage</title> </head> <body> <input type="button" value="添加" onclick="add()"/> <input type="button" value="读取" onclick="get()"/> <input type="button" value="删除" onclick="del()"/> <script type="text/javascript"> //添加 function add(){ //方法一 localStorage.setItem("name1","张三"); localStorage.setItem("1","张三1"); //方法二 localStorage["name2"]="李四"; //方法三 localStorage.name3="王五"; //存储对象 var str={name:"赵六",age:18} //序列化:把对象转换为String(由于JSON只能存储String) localStorage.str=JSON.stringify(str); } //读取 function get(){ //方法一 console.log(localStorage.getItem("name1")); //方法二 console.log(localStorage["name2"]); //方法三 console.log(localStorage.name3); //读取对象 //反序列化 var str=JSON.parse(localStorage.str) console.log(str.name); console.log(str.age); console.log(str); } //删除 function del(){ //根据Key值删除 localStorage.removeItem("name") //删除全部 localStorage.clear(); } </script> </body> </html>
结果:
添加的结果:
读取的结果:
移除的结果:
将数据临时保存在客户端session对象中。session对象就是会话对象,session中存储的数据独立于每一个客户,该数据会随着浏览器的关闭而消失。
sessionStorage的操做api与localStorage基本同样,在不手动清除的状况下localStorage永久保存,而sessionStorage只是临时暂存。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>本地临时存储:sessionStorage</title> </head> <body> <input type="button" value="添加" onclick="add()"/> <input type="button" value="读取" onclick="get()"/> <input type="button" value="删除" onclick="del()"/> <script type="text/javascript"> //添加 function add(){ //方法一 sessionStorage.setItem("name1","张三"); sessionStorage.setItem("1","张三1"); //方法二 sessionStorage["name2"]="李四"; //方法三 sessionStorage.name3="王五"; //存储对象 var str={name:"赵六",age:18} //序列化:把对象转换为String(由于JSON只能存储String) sessionStorage.str=JSON.stringify(str); } //读取 function get(){ //方法一 console.log(sessionStorage.getItem("name1")); //方法二 console.log(sessionStorage["name2"]); //方法三 console.log(sessionStorage.name3); //读取对象 //反序列化 var str=JSON.parse(sessionStorage.str) console.log(str.name); console.log(str.age); console.log(str); } //删除 function del(){ //根据Key值删除 sessionStorage.removeItem("name") //删除全部 sessionStorage.clear(); } </script> </body> </html>
结果:
添加的结果:
读取的结果:
删除的结果:
当程序修改localStorage与sessionStorage时将触发全局事件。
当setItem(),removeItem()或者clear() 方法被调用,而且数据真的发生了改变时,就会触发storage事件,若是须要进行监听数据处理,经过如下方法:
window.addEventListener(event,handleEvent, capture)
event:设置成storage
handleEvent:事件处理函数
capture:事件处理顺序,通常设置成false,表示采用冒泡方式处理
handleEvent处理事件的函数会接收到一个StorageEvent对象,该对象有如下属性:
key:被修改的键。
oldValue:修改前的值(若是是增长新的键值,则该属性为null)
newValue:修改后的值(若是是删除键值,则该属性为null)
url/uri:触发当前存储事件的页面的url
注意:storage改变的时候,触发这个事件会调用全部同域下其余窗口的storage事件,不过它自己触发storage即当前窗口是不会触发这个事件的(固然ie这个特例除外,它包含本身本事也会触发storage事件)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>得到localStorage的值</title> </head> <body> <script type="text/javascript"> console.log(localStorage.price); window.addEventListener("storage",function(obj){ alert(obj.oldValue+","+obj.newValue+","+obj.url); },true); </script> </body> </html>
运行结果以下:
Web SQL Database可让开发人员使用SQL语句操做客户端浏览器中嵌入的SQLite数据库 ,给开发人员提供了方便。对于简单的数据,使用sessionStorage和localStorage可以很好地完成存取,可是对于处理复杂的关系型数据,它就力不从心了。这也是 HTML 5 的“Web SQLDatabase”API 接口的应用所在。我把它理解成一个Html5环境下能够用Js执行CRUD的Web数据库
三个核心方法
openDatabase:这个方法使用现有数据库或建立新数据库建立数据库对象。
transaction:这个方法容许咱们根据状况控制事务提交或回滚。
executeSql:这个方法用于执行真实的SQL查询。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>商品信息</title> <style type="text/css"> #div{ width: 700px; height: 500px; margin:50px auto; border: 1px solid #4169E1; background-color: #FFFFFF; } #tab{ border-collapse: collapse; border-color: aquamarine; } #tab th{ width: 200px; text-align: center; } #fie{ position: relative; top: 50px; border-radius: 30px; } #tables,#deltable{ position: relative; top: 85px; } body{ background-color: #CCCCCC; } </style> </head> <body> <div id="div"> <input type="button" name="tables" id="tables" value="建立表" /> <input type="button" name="deltable" id="deltable" value="删除表" /> <table border="1" id="tab"> <caption><h1>商品信息</h1></caption> <tr> <th>编号</th> <th>名称</th> <th>价格</th> <th>操做</th> </tr> </table> <fieldset id="fie"> <legend>商品操做</legend> <p> <label for="name">商品名称:</label> <input type="text" name="name" id="name" value="" /> </p> <p> <label for="price">商品价格:</label> <input type="text" name="price" id="price" value="" /> </p> <input type="button" name="add" id="add" value="添加" /> <input type="button" name="alter" id="alter" value="修改" /> </fieldset> </div> </body> <script src="../js/jquery-1.11.3.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //页面加载时调用 $(function(){ databa() //建立/打开数据库 sel() //读取数据库 }) //获取数据库对象 var db; //建立/打开数据库 function databa(){ //(建立名称为commodity,版本为1.0,描述为产品数据库,3M大小的数据库,回调函数) db=openDatabase("commodity",1.0,"商品数据库",1024*1024*3,function(){ alert("数据库建立/打开成功!!!") }) } //建立表 $("#tables").click(function(){ //数据库对象.transaction(function(tx){tx.executeSql(sql语句,[?值],成功时的回调函数,失败时的回调函数)}) db.transaction(function(tx){ tx.executeSql("create table if not exists physics" +"(" +" id integer primary key autoincrement," +" name text not null," +" price double" +")" ,[] ,function(tx,result){ alert("建立成功") } ,function(tx,error){ alert("建立失败") } ) }); }) //删除表 $("#deltable").click(function(){ db.transaction(function(tx){ tx.executeSql( "drop table physics" ,[] ,function(tx,result){ alert("删除成功!!!") } ,function(tx,error){ alert("删除失败!!!") } ) }) }) //添加数据 $("#add").click(function(){ db.transaction(function(tx) { tx.executeSql( "insert into physics(name,price) values(?,?)", [$("#name").val(),$("#price").val()], function(tx, result) { alert("添加数据成功") sel() }, function(tx, error) { alert('添加数据失败' + error.message); }); }); }) //读取数据 function sel(){ //将表格中tr索引大于0的元素删除 $("#tab tr:gt(0)").remove(); db.transaction(function(tx) { tx.executeSql( "select id,name,price from physics", [], function(tx, result) { $.each(result.rows, function(i,obj) { var tr=$("<tr/>"); $("<td/>").text(obj["id"]).appendTo(tr); $("<td/>").text(obj["name"]).appendTo(tr); $("<td/>").text(obj["price"]).appendTo(tr); var del=$("<input type='button' value='删除' onclick='dels("+obj["id"]+")' />") var up=$("<input type='button' value='编辑' onclick='up("+obj["id"]+")'/>") $("<td/>").append(del).append(up).appendTo(tr); tr.appendTo("#tab"); }); }, function(tx, error) { }); }); } //修改:获取原数据 var bh=""; function up(id){ bh=id; db.transaction(function(tx){ tx.executeSql( "select name,price from physics where id=?" ,[id] ,function(tx,result){ $.each(result.rows, function(i,obj) { $("#name").val(obj["name"]); $("#price").val(obj["price"]); }); } ,function(tx,error){ } ) }) } //修改 $("#alter").click(function(){ db.transaction(function(tx){ tx.executeSql( "update physics set name=?,price=? where id=?" ,[$("#name").val(),$("#price").val(),bh] ,function(tx,recult){ alert("修改为功!!!") sel() } ,function(tx,error){ alert("修改失败!!!") } ) }) }) //删除数据 function dels(id){ db.transaction(function(tx){ tx.executeSql("delete from physics where id=?" ,[id] ,function(tx,result){ alert("删除成功!!!") sel() } ,function(tx,error){ alert("删除失败!!!") }) }) } </script> </html>
IndexedDB保存的是对象,而不是使用表保存数据。打开数据库使用indexDB.open方法,这方法有两个参数,第一个是数据库名称,第二个是数据版本号。
IndexedDB的操做彻底是异步进行的,每一次IndexedDB操做,都须要注册onerror或onsuccess事件处理程序。
对象存储空间(ObjectStore)能够想象成关系数据库的表,在初始化DB触发onupgradeneeded时,建立ObjectStore。使用createObjectStore方法,第一个参数是对象名,第二个参数是对象属性,通常是设置keyPath(做为键使用)。
由于对新数据的操做都须要在transaction中进行,而transaction又要求指定object store,因此咱们只能在建立数据库的时候初始化object store以供后面使用,这正是onupgradeneeded的一个重要做用
有了数据库后咱们天然但愿建立一个表用来存储数据,但indexedDB中没有表的概念,而是objectStore,一个数据库中能够包含多个objectStore,objectStore是一个灵活的数据结构,能够存放多种类型数据。也就是说一个objectStore至关于一张表,里面存储的每条数据和一个键相关联。
咱们可使用每条记录中的某个指定字段做为键值(keyPath),也可使用自动生成的递增数字做为键值(keyGenerator),也能够不指定。选择键的类型不一样,objectStore能够存储的数据结构也有差别
不使用—>任意值,可是没添加一条数据的时候须要指定键参数
keyPath—>Javascript对象,对象必须有一属性做为键值
keyGenerator—>任意值(db.createObjectStore('students',{autoIncrement: true});)
都使用—>Javascript对象,若是对象中有keyPath指定的属性则不生成新的键值,若是没有自动生成递增键值,填充keyPath指定属性
全部读取或修改数据的操做,都要经过事务来完成。建立事务使用transaction方法,第一个参数是须要访问的ObjectStore,第二个参数是访问模式(readwrite可读可写、readonly只读,默认是只读)。
使用事务能够直接经过键检索单个对象,而须要检索多个对象时候就须要使用游标。游标是指向结果集的指针,不提早收集结果。游标指针会先指向结果中的第一项,在接到查找下一项指令时,才会指向下一项。
这里有几点要注意:
1. 若是须要修改或删除数据,就须要打开成读写模式。
2. cursor的非空校验是必要的。
3. 修改或删除的操做也是有onsuccess和onerror的,只是在示例中没有写出来。
4. 调用continue才会移动到下一项
另外能够设置游标的键范围和游标的方向,即打开openCursor方法时能够传这两个参数(openCursor(键范围,方向)),第一个参数是object类型,第二个参数是字符串类型。
键范围由IDBKeyRange的实例表示。
IDBKeyRange.only('001'); //只想要键为001的结果 IDBKeyRange.lowerBound('002'); //从键为002开始,到最后 IDBKeyRange.lowerBound('002', true); //从键为002开始,但忽略002,到最后 IDBKeyRange.upperBound('002'); //从头开始,到键为002为止 IDBKeyRange.upperBound('002', true); //从头开始,到键为002为止,但忽略002 IDBKeyRange.bound('001', '005'); //从001开始,到为005为止 IDBKeyRange.bound('001', '005', true, true); //从001开始,到为005为止,但忽略00一、005
next : 从第一项到最后一项(默认)
prev : 从最后一项到第一项
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>IndexedDb:商品信息</title> <style type="text/css"> #div{ width: 700px; height: 500px; margin:50px auto; border: 1px solid #4169E1; background-color: #FFFFFF; } #tab{ border-collapse: collapse; border-color: aquamarine; } #tab th{ width: 200px; text-align: center; } #fie{ position: relative; top: 50px; border-radius: 30px; } #tables,#deltable{ position: relative; top: 85px; } </style> </head> <body> <div id="div"> <table border="1" id="tab"> <caption><h1>商品信息</h1></caption> <tr> <th>编号</th> <th>名称</th> <th>价格</th> <th>操做</th> </tr> </table> <fieldset id="fie"> <legend>商品操做</legend> <p> <label for="name">商品编号:</label> <input type="text" name="id" id="id" value="" /> </p> <p> <label for="name">商品名称:</label> <input type="text" name="name" id="name" value="" /> </p> <p> <label for="price">商品价格:</label> <input type="text" name="price" id="price" value="" /> </p> <input type="button" name="add" id="add" value="添加" /> <input type="button" name="alter" id="alter" value="修改" /> </fieldset> </div> <script src="../js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> $(function(){ databas(); }) var db; //建立数据库、建立表 function databas(){ //建立一个名为commodity,版本为2的数据库 var requst=indexedDB.open("commodity",2); //绑定成功时的回调函数 requst.onsuccess=function(e){ db=e.target.result; console.log("建立数据库成功!!!"); get() } //绑定失败时的回调函数 requst.onerror=function(e){ console.log("错误:"+e.target.errorCode || e.target.error) }; //建立表 requst.onupgradeneeded =function(e){ e.target.result.createObjectStore("commoditys",{"keyPath":"id"}) console.log("建立表成功") } } //读取数据 function get(){ $("#id").val("") $("#name").val("") $("#price").val("") $("#tab tr:gt(0)").remove(); var request=db.transaction("commoditys","readonly").objectStore("commoditys").openCursor(); request.onsuccess=function(e){ var cursor =e.target.result; if(cursor){ var obj=cursor.value; var tr=$("<tr/>") $("<td/>").text(obj.id).appendTo(tr); $("<td/>").text(obj.name).appendTo(tr); $("<td/>").text(obj.price).appendTo(tr); var del=$("<input type='button' value='删除' id='del' onclick='del(this,"+obj.id+")'>"); var up=$("<input type='button' value='编辑' id='up' onclick='up(this,"+obj.id+")'>"); $("<td/>").append(del).append(up).appendTo(tr); tr.appendTo($("#tab")); cursor.continue() } } } function text(){ return { id:$("#id").val(), name:$("#name").val(), price:$("#price").val() } } //添加数据 $("#add").click(function(){ var tx=db.transaction("commoditys","readwrite").objectStore("commoditys").add(text()); get() alert("添加成功") }) //获取要修改数据 function up(t,id){ var request=db.transaction("commoditys","readonly").objectStore("commoditys").openCursor(""+id+""); request.onsuccess=function(e){ var cursor =e.target.result; if (cursor) { var obj=cursor.value; $("#id").val(obj.id); $("#name").val(obj.name); $("#price").val(obj.price); } } } //修改数据 $("#alter").click(function(){ var requset=db.transaction("commoditys","readwrite").objectStore("commoditys").put(text()); requset.onsuccess=function(e){ console.log("修改为功") get() } }) //删除数据 function del(t,id){ if(confirm("您肯定要删除吗?")){ var requset=db.transaction("commoditys","readwrite").objectStore("commoditys").delete(""+id+""); requset.onsuccess=function(e){ alert("删除成功!!!") get() } requset.onerror=function(e){ alert("删除失败") } } } </script> </body> </html>