localStorage扩容

更新日期: 2022-01-14阅读: 1.2k标签: 缓存

浏览器提供的localStorage本地存储的最大空间是5M,如果不够用呢,这时候就需要考虑来给localStorage扩容。


思路如下:

  1. 在【A域】下引入【B域】,【A域】空间足够时,读写由【A域】来完成,数据存在【A域】下;当【A域】空间不够时,读写由【B域】来完成,数据存在【B域】下

  2. 【A域】空间不够需要在【B域】读写时,通过postMessage 向【B域】发送跨域消息,【B域】监听跨域消息,在接到指定的消息时进行读写操作

  3. 【B域】接到跨域消息时,如果是写入删除可以不做什么,如果是读取,就要先读取本域本地数据通过postMessage向父页面发送消息

  4. 【A域】在读取【B域】数据时就需要监听来自【B域】的跨域消息


注意事项:

  1. window.postMessage()方法,向【B域】发消息,应用window.frames[0].postMessage() 这样iframe内的【B域】才可以接到

  2. 同理,【B域】向 【A域】发消息时应用,window.parent.postMessage()

  3. 【A域】的逻辑一定要在iframe 加载完成后进行


代码实现:

【A域】的页面如下:

index.html

<!DOCTYPE html>
<html>
    <head>
	    <meta charset="utf-8" />
	<title></title>
    </head>
	<body>
    	<button class="set">存储</button>
    	<button class="get">读取</button>
    	<button class="remove">删除</button>
    	<iframe src="http://localhost:8000/storage.html"></iframe>   //嵌入【B域】的一个空页面
    </body>
    <script src="js/localStorage.js"></script>
</html>

由于需要判断【A域】的空间是否足够,所以需要计算【A域】已经被占用的空间。那么localStorage中的字符串以什么编码格式存储的呢?
经过反复试验发现,当使用utf-16的编码方式进行计算时,当存储的字符串大于5M时,浏览区就会报错:字符串大小超过最大值。
所以localStorage中的字符串是以utf-16进行编码的。

localStorage.js

/*这段代码是用来测试localStorage中字符串的编码格式*/
/**
* 计算字符串所占的内存字节数,默认使用UTF-8的编码方式计算,也可制定为UTF-16
* UTF-8 是一种可变长度的 Unicode 编码格式,使用一至四个字节为每个字符编码
* 
* 000000 - 00007F(128个代码)      0zzzzzzz(00-7F)                             一个字节
* 000080 - 0007FF(1920个代码)     110yyyyy(C0-DF) 10zzzzzz(80-BF)             两个字节
* 000800 - 00D7FF 
00E000 - 00FFFF(61440个代码)    1110xxxx(E0-EF) 10yyyyyy 10zzzzzz           三个字节
* 010000 - 10FFFF(1048576个代码)  11110www(F0-F7) 10xxxxxx 10yyyyyy 10zzzzzz  四个字节
* 
* 注: Unicode在范围 D800-DFFF 中不存在任何字符
* 
* UTF-16 大部分使用两个字节编码,编码超出 65535 的使用四个字节
* 000000 - 00FFFF  两个字节
* 010000 - 10FFFF  四个字节
* 
* @param  {String} str 
* @param  {String} charset utf-8, utf-16
* @return {Number}
*/

function sizeof(str,charset){
    var strCode=0,charCode;
    charset = charset?charset.toLowerCase():'';
    if(charset=='utf-16'||charset=='utf16'){
	    for(var i=0,len=str.length;i<len;i++){
	    	charCode = str.charCodeAt(i);
	    	strCode += charCode<0xffff?2:4;
	    }
    }else{
	    for(var i=0,len=str.length;i<len;i++){
	    	charCode = str.charCodeAt(i);
	    	strCode += (charCode<0x007f&&1)||(charCode<0x07ff&&2)||(charCode<0xffff&&3)||4;
    	}
    }
	return strCode/1024/1024/2;
}
/*测试localStorage中字符串的编码格式结束*/

function storage(type,key,value){
    var val = localStorage.getItem(key);
	switch (type){
    	case 'get':
		    if(val){
		    	return val;
		    }else{
		    	return window.frames[0].postMessage(JSON.stringify({type:type,key:key}),'http://localhost:8000');
		    }
		    break;
	    case 'set':
	    	if(!val&&sizeofLocal()+sizeof(value)>5){
		    	            window.frames[0].postMessage(JSON.stringify({type:type,key:key,value:value}),'http://localhost:8000');

		    }else{
			    localStorage.setItem(key,value);
	    	}
	    break;
	    case 'remove':
		    if(val){
		    	localStorage.removeItem(key);
	    	}else{
		    	window.frames[0].postMessage(JSON.stringify({type:type,key:key}),'http://localhost:8000');   
		    }
	    	break;
	    default:
	    	break;
	}
}

function sizeofLocal(){
    var myStr = '',charCode,strCode=0;
    for(item in localStorage){
    	if(localStorage.hasOwnProperty(item)){
	    	myStr += localStorage.getItem(item);
    	}
    }
	for(var i=0,len=myStr.length;i<len;i++){
    	charCode = myStr.charCodeAt(i);
    	strCode += charCode<0xffff?2:4;
    }
    return strCode/1024/1024/2;
}

var myStr='';
for(var i=0;i<1024*1200;i++){
	myStr += 1+'12'+'啦';
}

document.querySelector(".set").onclick = function(){
	storage("set","yoyo",myStr);
}

document.querySelector(".get").onclick = function(){
	storage("get","yoyo");
    window.addEventListener('message',function(e){
	    window.myStorage = e.data;	
	})
}

document.querySelector(".remove").onclick = function(){
    storage("remove","yoyo");
}

【B域】的页面如下

storage.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title></title>
</head>
<body>

</body>
<script type="text/javascript">
	var fn = function(){};
	fn.prototype = {
		setLocal:function(key,value){
			localStorage.setItem(key,value);
		},
		getLocal:function(key){
			return localStorage.getItem(key);
		},
		removeLocal:function(key){
			localStorage.removeItem(key);
		},
		bindEvent:function(){
			var self = this;
			//监听
			window.addEventListener('message',function(e){
				if(window.parent!=e.source) return;
				var option = JSON.parse(e.data);
				if(option.type.toLowerCase()=="get"){
					var data = self.getLocal(option.key);
					window.parent.postMessage(data,'*');
				}
				option.type.toLowerCase()=="set"&&self.setLocal(option.key,option.value);
				option.type.toLowerCase()=="remove"&&self.removeLocal(option.key);
			})
		},
		init:function(){
			var self = this;
			self.bindEvent();
		}
	}
	var tools = new fn();
	tools.init();
</script>

链接: https://fly63.com/article/detial/11036

浏览器缓存_HTTP强缓存和协商缓存

浏览器缓存主要分为强强缓存(也称本地缓存)和协商缓存(也称弱缓存),强缓存是利用http头中的Expires和Cache-Control两个字段来控制的,用来表示资源的缓存时间。协商缓存就是由服务器来确定缓存资源是否可用.

angularjs 缓存详解

一个缓存就是一个组件,它可以透明地存储数据,以便未来可以更快地服务于请求。缓存能够服务的请求越多,整体系统性能就提升得越多。

浏览器缓存问题原理以及解决方案

浏览器缓存就是把一个已经请求过的Web资源(如html页面,图片,js,数据等)拷贝一份副本储存在浏览器中,为什么使用缓存:减少网络带宽消耗,降低服务器压力,减少网络延迟,加快页面打开速度

Web缓存相关知识整理

一个H5页面在APP端,如果勾选已读状态,则下次打开该链接,会跳过此页面。用到了HTML5 的本地存储 API 中的 localStorage作为解决方案,回顾了下Web缓存的知识

使用缓存加速之后的网站访问过程变化

在描述CDN的实现原理之前,让我们先看传统的未加缓存服务的访问过程,以便了解CDN缓存访问方式与未加缓存访问方式的差别,用户访问未使用CDN缓存网站的过程为:用户向浏览器提供要访问的域名;

html页面清除缓存

页面打开时,由于缓存的存在,刚刚更新的数据有时无法在页面得到刷新,当这个页面作为模式窗口被打开时问题更为明显, 如何将缓存清掉?

HTTP之缓存 Cache-Control

通过在Response Header设置Cache-Control head 信息可以控制浏览器的缓存行为。我们先来看一下Cache-Control可以设置哪些值:缓存头Cache-Control只能在服务端设置,在客户端是由浏览器设置的,自己不能修改它的值。

工程化_前端静态资源缓存策略

增量更新是目前大部分团队采用的缓存更新方案,能让用户在无感知的情况获取最新内容。具体实现方式通常是(一般我们通过构建工具来实现,比如webpack):

前端静态资源自动化处理版本号防缓存

浏览器会默认缓存网站的静态资源文件,如:js文件、css文件、图片等。缓存带来网站性能提升的同时也带来了一些困扰,最常见的问题就是不能及时更新静态资源,造成新版本发布时用户无法及时看到新版本的变化,严重影响了用户体验。

vue后台管理系统解决keep-alive页面路由参数变化时缓存问题

一个后台管理系统,一个列表页A路由配置需要缓存,另一个页面B里面有多个跳转到A路由的链接。问题描述:首先访问/A?id=1页面,然后到B页面再点击访问A?id=2的页面,发现由于页面A设置了缓存,数据还是id=1的数据,并没有更新。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!