关于存储
之前了解的存储有数据库、cache、磁盘文件、内存
H5之前浏览器端的存储用的几乎都是cookies,它有几个特点:
- http请求头中携带(感觉有些臃肿,毕竟一次http请求的步骤有三次握手,四次挥手)
- 大小限定4K
- 主Domain污染
- 还有一些安全问题
H5存储的优点:
- 解决4K的大小问题
- 解决请求头常带存储信息的问题
- 解决关系型存储的问题
- 跨浏览器
H5存储方式
- 本地存储(localstorage&&sessionstorage)
- 离线缓存(application cache)
- IndexedDB和Web SQL
H5本地存储
API:localstorage&&sessionstorage
存储形式:key-value
过期:
localstorage:永久存储,除非手动删除
sessionstorage:重新打开页面或关闭浏览器就失效
大小:官方规定每个域名好像能存5M
使用方法:
- localstorage(sessionstorage) API介绍
- getItem(如:localstorage.getItem(‘test’)
- setItem(如:localstorage.setItem(‘test’,’测试’))
- removeItem
- key(如:localstorage.key(0),取出索引为0的key)
- clear(如:localstorage.clear(),清除所有的key-value)
例子(localstorage中存取图片):
var src="test.jpg";
function set(key){
var img=document.createElement('img');
//当图片加载完成的时候触发回调函数
img.addEventListener('load',function(){
var imgCanvas=document.createElement('canvas');
imgContext=imgCanvas.getContext('2d');
//确保canvas元素大小与图片尺寸一致
imgCanvas.width=this.width;
imgCanvas.height=this.height;
//渲染图片到canvas中
imgContext.drawImage(this,0,0,this.width,this.height);
//用data url的形式取出
var imgAsDataURL=imgCanvas.toDataURL("image/png");
//保存到本地存储中
try{
localstorage.setItem(key,imgAsDataURL);
}catch(e){
console.log("storage failed:"+e);
}
},false);//false- 默认。事件句柄在冒泡阶段执行
img.src=src;
}
function get(key){//从本地缓存获取图片并渲染
var srcStr=localStorage.getItem(key);
var imgObj=document.createElement('img');
imgObj.src=srcStr;
document.body.appendChild(imgObj);
}
使用时的注意事项:
- 使用前要判断浏览器是否支持
- 写数据时,要异常处理,避免超出容量报错
- 避免把敏感信息存入localStorage
- key的唯一性
使用限制:
- 存储更新策略,过期控制
- 子域名之间不能共享存储数据
- 超出存储最大容量之后如何存储(运用LRU,FIFO淘汰一些过时数据)
- server端如何取到(如果有相应需求)
例子(过期控制):
function set(key,v){
//当前时间
var curTime=new Date().getTime();
localStorage.setItem(key,JSON.stringify({data:v,time:curTime}));
}
//exp为自定义的存储时间,如1000*60(一分钟)
function get(key,exp){
var data=localStorage.getItem(key);
var dataObj=JSON.parse(data);
if(new Date().getTime()-dataObj.time>exp){
localStorage.removeItem(key);
console.log("过期了");
}else{
console.log('data='+dataObj.data);
}
}
使用场景:
- 利用本地存储,减少网络传输
- 弱网络环境下,高延迟,低带宽,尽量把数据本地化
IndexedDB
indexedDB database
一种能在浏览器中持久的存储结构化数据的数据库,并且为web应用提供了丰富的查询能力
它是按域名分配独立空间,一个独立域名下可以创建多个数据库,每个数据库可以创建多个对象存储空间(表),一个对象存储空间可以存储多个对象数据
比如有两个域名:a.qq.com和b.qq.com,你可以在其中一个域名下创建多个数据库,如:DB_A 和 DB_B, 又在DB_A下创建多个表,如table_A1,table_A2
它主要是应用于离线web应用场景,因为我暂时用不到这项功能,所以了解的不多,就不介绍了
H5离线缓存
它可以让Web应用在离线情况下继续使用,通过manifest文件指明需要缓存的资源
检测是否在线:
navigator.onLine
原理图:
manifest文件示例:
CACHE MANIFEST
#version n.n
CACHE:
#需要缓存的文件
/css/sample.css
/images/image.jpg
NETWORK:
#每次需要重新拉取的文件
*
FALLBACK:
#离线状况下代替文件
/offline.html
如果你的manifest文件有更新,只需要修改version的版本号,就会重新拉取文件,更新app cache
在HTML页面中引用manifest文件
<html manifest="sample.appcache">
可以是绝对路径也可以是相对路径
最后就是tomcat的配置,需要在tomcat下的conf/web.xml中追加以下内容(copy过去即可),让tomcat认识manifest文件。
<mime-mapping>
<extension>manifest</extension>
<mime-type>text/cache-manifest</mime-type>
</mime-mapping>
如何更新
如果有修改资源文件,必须通过修改manifest文件来刷新被缓存的文件列表
优势
- 完全离线
- 资源被缓存,加载更快
- 降低server负载
使用缺陷
- 含有manifest属性的当前请求页无论如何都会被缓存
- 更新需要建立在manifest文件的更新,文件更新后是需要页面再次刷新的(需要2次刷新才能获取到新资源)
- 更新是全局性的,无法单独更新某个文件(无法单点更新)
- 对于链接的参数变化是敏感的,任何一个参数的修改都会被master重新缓存(重复缓存含参页面)index.html和index.html?renew=1会被认为是不同文件,分别缓存
适用场景
- 单地址的页面
- 对实时性要求不高的业务
- 离线webapp