客户端存储历程
关于浏览器缓存和本地存储我接触的时间不长,今天下午抽时间学习了一下,下面是我结合视频、文献资料整理的一些关于html本地存储的一些资料,希望大家会用到!不过我还是觉得application cache是一个很大的坑,第一次用的时候要当心!
-远古时代
-HTML5时代
关于存储
存储包含:cache(缓存)、磁盘文件、数据库、内存
h5之前
cookies
缺点:
cookies在浏览器端的存储形态
Name, Value, Dommain(域名), Path(路径), EXPIR…(过期时间), size(大小)
UserData
H5的几种存储方式
几种存储形式
API
-locastorage && sessionstorage
存储形式
-key > value
过期
-永久存储,永不失效,除非手动删除
大小
-官方给出的文档是,每个域名5M
使用案例
//localstotage localstotage.setItem('test1','test1');//新建一个name为test1、value为test1的字段 localstorage.getItem('test1');//获取第一个name为test1的字段的value localstorage.key(0);//获取第一个键值对的数据 localstorage.clear();//清楚存储 //sessionstorage sessionstorage.setItem('test1','test1');//新建一个name为test1、value为test1的字段
使用注意事项:
使用限制
使用场景
web sql和indexedDB
一种能在浏览器中持久地存储结构化数据的数据库,并且为web应用提供了丰富的查询能力;
浏览器支持
chrome 11+ ,opera不支持 ,firefox 4+ ,ie10+
打开数据库
var request=window.indexedDB.open('testDB');
除了result,IDBOpenDBRequest接口定义了几个重要属性
所谓异步API是指并不是这条指令执行完毕,我们就可以使用request.result来获取indexedDB对象了,就像使用ajax一样,语句执行完并不代表已经获取到了对象,所以我们一般在其回调函数中处理。
创建数据库
刚才的语句已经展示了如何打开一个indexedDB数据库,调用indexedDB.open方法就可以创建或者打开一个indexedDB。看一个完整的处理
function openDB (name) { var request=window.indexedDB.open(name); request.onerror=function(e){ console.log('OPen Error!'); }; request.onsuccess=function(e){ myDB.db=e.target.result; }; } var myDB={ name:'test', version:1, db:null }; openDB(myDB.name);
object store
有了数据库后我们自然希望创建一个表用来存储数据,但indexedDB中没有表的概念,而是objectStore,一个数据库中可以包含多个objectStore,objectStore是一个灵活的数据结构,可以存放多种类型数据。也就是说一个objectStore相当于一张表,里面存储的每条数据和一个键相关联。
我们可以使用每条记录中的某个指定字段作为键值(keyPath),也可以使用自动生成的递增数字作为键值(keyGenerator),也可以不指定。选择键的类型不同,objectStore可以存储的数据结构也有差异
键类型 | 存储数据 |
不使用 | 任意值,但是没添加一条数据的时候需要指定键参数 |
keyPath | Javascript对象,对象必须有一属性作为键值 |
keyGenerator | 任意值 |
都使用 | Javascript对象,如果对象中有keyPath指定的属性则不生成新的键值,如果没有自动生成递增键值,填充keyPath指定属性 |
事务
在对新数据库做任何事情之前,需要开始一个事务。事务中需要指定该事务跨越哪些object store。
事务具有三种模式
给object store添加数据
调用数据库实例的createObjectStore方法可以创建object store,方法有两个参数:store name和键类型。调用store的add方法添加数据。有了上面知识,我们可以向object store内添加数据了
keyPath
因为对新数据的操作都需要在transaction中进行,而transaction又要求指定object store,所以我们只能在创建数据库的时候初始化object store以供后面使用,这正是onupgradeneeded的一个重要作用,修改一下之前代码
function openDB (name,version) { var version=version || 1; var request=window.indexedDB.open(name,version); request.onerror=function(e){ console.log(e.currentTarget.error.message); }; request.onsuccess=function(e){ myDB.db=e.target.result; }; request.onupgradeneeded=function(e){ var db=e.target.result; if(!db.objectStoreNames.contains('students')){ db.createObjectStore('students',{keyPath:"id"}); } console.log('DB version changed to '+version); }; }
这样在创建数据库的时候我们就为其添加了一个名为students的object store,准备一些数据以供添加
var students=[{ id:1001, name:"Byron", age:24 },{ id:1002, name:"Frank", age:30 },{ id:1003, name:"Aaron", age:26 }]; function addData(db,storeName){ var transaction=db.transaction(storeName,'readwrite'); var store=transaction.objectStore(storeName); for(var i=0;i<students.length;i++){ store.add(students[i]); } } openDB(myDB.name,myDB.version); setTimeout(function(){ addData(myDB.db,'students'); },1000);
这样我们就在students object store里添加了三条记录,以id为键,在chrome控制台看看效果
keyGenerate
function openDB (name,version) { var version=version || 1; var request=window.indexedDB.open(name,version); request.onerror=function(e){ console.log(e.currentTarget.error.message); }; request.onsuccess=function(e){ myDB.db=e.target.result; }; request.onupgradeneeded=function(e){ var db=e.target.result; if(!db.objectStoreNames.contains('students')){ db.createObjectStore('students',{autoIncrement: true}); } console.log('DB version changed to '+version); }; }
剩下的两种方式有兴趣同学可以自己摸索一下了
查找数据
可以调用object store的get方法通过键获取数据,以使用keyPath做键为例
function getDataByKey(db,storeName,value){ var transaction=db.transaction(storeName,'readwrite'); var store=transaction.objectStore(storeName); var request=store.get(value); request.onsuccess=function(e){ var student=e.target.result; console.log(student.name); }; }
更新数据
可以调用object store的put方法更新数据,会自动替换键值相同的记录,达到更新目的,没有相同的则添加,以使用keyPath做键为例
function updateDataByKey(db,storeName,value){ var transaction=db.transaction(storeName,'readwrite'); var store=transaction.objectStore(storeName); var request=store.get(value); request.onsuccess=function(e){ var student=e.target.result; student.age=35; store.put(student); }; }
删除数据及object store
调用object store的delete方法根据键值删除记录
function deleteDataByKey(db,storeName,value){ var transaction=db.transaction(storeName,'readwrite'); var store=transaction.objectStore(storeName); store.delete(value); }
调用object store的clear方法可以清空object store
function clearObjectStore(db,storeName){ var transaction=db.transaction(storeName,'readwrite'); var store=transaction.objectStore(storeName); store.clear(); }
调用数据库实例的deleteObjectStore方法可以删除一个object store,这个就得在onupgradeneeded里面调用了
if(db.objectStoreNames.contains('students')){ db.deleteObjectStore('students'); }
H5离线缓存
什么是离线缓存(offline application)
它可以让web应用在离线的情况下继续使用,通过manifest文件指明需要缓存的资源
检测是否在线
navigator.onLine
只要每次更新manifest就可以重新加载资源
CHCHE MANIFEST #version n.n CACHE: #需要缓存的文件 /css/sample.css /images/image.jpg NETWORK: #每次重新拉取的文件 * FALLBACK #离线状况下代替文件 /offline.html
在html页面引入manifest文件
<html manifest="sample.appcache">
在服务器添加mime-type text/cache-manifest
更新测试(Test for updates)
做个测试来看一下是否可以通过Javascript来程序操作一个可用的更新过的缓存清单。缓存已经在检测更新的脚本使用之前被更新,脚本会时常检测window.applicationCache.status.
function onUpdateReady(){ alert('found new version!"); } window.applicationCache.addEventListener('updateready', onUpdateReady); if(window.applicationCache.status == window.applicationCache.UPDATEREADY){ onUpdateReady(); }
你可以使用window.applicationCache.update()手动测验一个新的清单。
希望,把功能性,和构造,按顺序讲一下
getDataByKey这个获取数据参数那里value是什么啊?