前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript客户端存储

JavaScript客户端存储

作者头像
奋飛
发布2019-08-15 16:08:15
1.6K0
发布2019-08-15 16:08:15
举报
文章被收录于专栏:Super 前端Super 前端

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://ligang.blog.csdn.net/article/details/42877059

navigator.online:浏览器是否连接到网络 常见的客户端存储有几种:第一种,Web存储,其中包含localStorage对象和sessionStorage对象;第二种,Cookie,其作为一种被服务端脚本使用的客户端存储机制。

一、localStorage和sessionStorage

1. 二者区别在于存储的有效期和作用域的不同: localStorage存储的数据时永久性的,作用域是限定在文档源级别的(文档源是通过协议、主机、端口三者确定)。注意其作用域也受到浏览器供应商限制。 sessionStorage作用域也是限定在文档源中,因此非同源文档无法共享sessionStorage,不仅如此,其作用域还被限定在窗口中(顶级窗口)。一个浏览器标签页包含两个iframe是可以共享的。

代码语言:javascript
复制
localStorage.setItem("x",1);	//以“x”的名字存储一个数值
localStorage.getItem("x");	//获取数值

for(var i=0;i<localStorage.length;i++){
	var name = localStorage.key(i);
	var value = localStorage.getItem(name);
}

localStorage.removeItem("x");	//删除“x”项
localStorage.clear();	//全部删除

//存储对象的处理
var o = {x:1};
var oStr = JSON.stringify(o);	//由于存储的内容都是字符串,序列化对象
localStorage.setItem("o",oStr);
localStorage.getItem("o");	//{"x":1} 	typeof类型:string
JSON.parse(localStorage.getItem("o")).x;	//反序列化

// 识别使用哪种存储机制
var memory = window.localStorage || (window.UserDataStorage && new UserDataStorage()) || new CookieStorage();	
// 然后在对应机制中获取数据
memory.getItem("name");

2. 存储事件 无论什么时候存储在localStorage和sessionStorage的数据发生改变,浏览器都会在其他对该数据可见的窗口对象上触发存储事件(但是,在对数据进行改变的窗口对象上是不会触发的)。为存储事件注册处理程序可以通过addEventListener()方法(IE下使用addEvent()方法)。监听storage。

代码语言:javascript
复制
if(window.addEventListener){
	window.addEventListener("storage",handle_storage,false);
}else if(window.attachEvent){
	window.attachEvent("onstorage",handle_storage);
}


function handle_storage(e){
	if(!e){
		e=window.event;
	}
	//showStorage();
}

对于事件变量e,是一个StorageEvent对象,提供了一些实用的属性,可以很好的观察键值对的变化 storageArea: 表示存储类型(Session或Local) key:发生改变项的key oldValue: key的原值 newValue:key的新值 url*:key改变发生的URL【使用url属性前,你应该先检查它是否存在,如果没有url属性,则应该使用uri属性】 最后需要注意的是,localStorage和存储事件都是采用广播机制,浏览器会对目前正在访问同样站点的所有窗口发送消息。

二、Cookie

绝大数浏览器可以通过navigator.cookieEnabled这个属性来检测Cookie是否启用! Cookie的有效期和整个浏览器进程而不是单个浏览器窗口有效期一致。 默认情况下,cookie和创建它的WEB页面有关,并对该WEB页面以及和该WEB页面同目录或者子目录的其他WEB页面可见。 将cookie的路径设置为“/”等于是让cookie和localStorage拥有同样的作用域。 1. 保存cookie cookie的名/值中的值是不允许包括分号、逗号和空白符,因此,在存储前一般可以采用JavaScript核心的全局函数encodeURIComponent()对值进行编码。

代码语言:javascript
复制
// 以name/value形式存储cookie
function setCookie(name,value,daysToLive){
	var cookie = name + "=" + encodeURIComponent(value);
	if(typeof daysToLive === 'number'){
		cookie += "; max-age=" + (daysToLive*60*60*24);	 //分号空格
	}
	document.cookie = cookie;
}

// 读取全部cookie
function getCookies(){
	var cookie = {};
	var all = document.cookie;
	if(all === ""){
		return cookie;
	}
	var list = all.split("; "); //注意有空格
	for(var i=0; i<list.length; i++){
		var item = list[i];
		var p = item.indexOf("="); //查找第一个“=”符号
		var name = item.substring(0,p);
		var value = item.substring(p+1);
		value = decodeURIComponent(value);
		cookie[name] = value;
	}
	return cookie;
}

// 读取指定名称cookie项
function getCookie(name){
	var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
	if(arr=document.cookie.match(reg)){
		// unescape() 函数可对通过 escape() 编码的字符串进行解码
		// ECMAScript v3 已从标准中删除了 unescape() 函数,建议使用 decodeURI() 和 decodeURIComponent() 
		//return unescape(arr[2]);
		return decodeURIComponent(arr[2]);
	}else {
		return null;
	};
} //getCookie

// 删除指定cookie项
function delCookie(name) { 
    var exp = new Date(); 
    exp.setTime(exp.getTime() - 1); //有效期,为当前时间的前1s
    var cval=getCookie(name); 
    if(cval!=null) 
    	// 把Date对象转换为"格林威治时间 (GMT)"形式的字符串
        document.cookie= name + "="+cval+";expires="+exp.toGMTString();  
} 

// =======测试=========
setCookie('name',"ligang","100000");
setCookie('age',28,"100000");
console.log(getCookies()['name'])
var age = getCookie('age');
console.log(age)
delCookie('age');
console.log(getCookie('age'))

三、应用程序缓存

首先建立一个清单,包含应用程序依赖的所有URL列表;然后,通过在应用程序在主HTML页面的<html>标签中设置manifest属性,指向到该清单文件即可。

代码语言:javascript
复制
<!DOCTYPE HTML>
<html manifest="myapp.appcache">
<head></head>
<body></body>
</html>

#清单文件中的首行内容必须以"CACHE MANIFEST"字符串开头 #myapp.appcache 示例:

代码语言:javascript
复制
CACHE MANIFEST

# myapp version 1(更新这个数字以便让浏览器重新下载这个文件)

# 直接缓存的文件
CACHE:
	../css/*	
	../js/site/*


# 必须在线访问
NETWORK: 
	index.do
	
# 替代方案【从网络中载入videos/路径下文件失败,会采用缓存资源offline_help.html来代替】  
FALLBACK:  
	vidoes/ offline_help.html

注意,浏览器只检查清单文件,而不会去检查缓存的文件是否有更新。 在更新清单文件之后,用户必须载入应用两次才能保证最新的版本生效:第一次是从缓存中载入老版本随后更新缓存;第二次才从缓存中载入新的版本。 浏览器在更新缓存中会触发一些事件,可以根据这些事件来给反馈信息给用户:

代码语言:javascript
复制
applicationCache.onupdateready = function(){
	var reload = confirm("发现新版本,您是否更新?");
	if(reload) location.reload();
}

四、离线Web应用

可以使用localStorage来存储应用数据,然后当在线的时候再将数据长传到服务器。 示例:一个简单的记事本程序 note.html:

代码语言:javascript
复制
<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="utf-8">
		<title>note</title>
		<script src="note.js"></script>
		<style>
			#editor {width: 100%; height: 250px;}
			#statusline {width: 100%;}
		</style>
	</head>
	<body>
		<div id="toolbar">
			<button id="savebutton" οnclick="save()">Save</button>
			<button οnclick="sync();">Sync Note</button>
			<button οnclick="applicationCache.update();">Update Application</button>
		</div>
		<textarea id="editor"></textarea>
		<div id="statusline"></div>
	</body>
</html>

note.js:

代码语言:javascript
复制
// 全局变量
var editor,statusline,savebutton,idletimer;

window.onload = function(){
	//第一次载入时,初始化本地存储
	if(localStorage.note == null) localStorage.note = "";
	if(localStorage.lastModified == null) localStorage.lastModified = 0;
	if(localStorage.lastSaved == null) localStorage.lastSaved =0;

	// 查找元素,并初始化全局变量
	editor = document.getElementById("editor");
	statusline = document.getElementById("statusline");
	savebutton = document.getElementById("savebutton");

	// 初始化编辑器,将保存的笔记数据填充为其内容
	editor.value = localStorage.note;
	// 同步前禁止编辑
	editor.disabled = true;

	// 一旦文本区有内容输入
	editor.addEventListener("input", function(e){
		// 将新的值保存到localStorage中
		localStorage.note = editor.value;
		localStorage.lastModified = Date.now();
		// 重置闲置计时器
		if(idletimer) clearTimeout(idletimer);
		idletimer = setTimeout(save, 5000);
		// 启用保存按钮
		savebutton.disabled = false;
	},false);

	// 每次载入应用程序时,尝试同步服务器
	sync();
};

// 离开页面前保存数据到服务器
window.onbeforeunload = function(){
	if(localStorage.lastModified > localStroage.lastModified)
		save();
};

// 离线时,通知用户
window.onoffline = function(){
	status("Offline");
};

// 再次返回在线状态时,进行同步
window.ononline = function(){
	sync();
};


// 当有新版本应用的时候,提醒用户
// 这里我们也可以采用location.reload()方法来强制重新载入应用
window.applicationCache.onupdateready = function(){
	status("A new version of this application is available. Reload to run it.");
};

// 当没有新版本的时候也通知用户
window.applicationCache.onnoupdate = function(){
	status("You are running the lasted version of the application.");
};

// 用于在状态栏显示状态消息的一个函数
function status(msg){
	statusline.innerHTML = msg;
}

// 每当笔记内容更新后,如果用户停止编辑超过5分钟,就会自动将笔记本上传到服务器(在线状态下)
function save(){
	if(idletimer) clearTimeout(idletimer);
	idletimer = null;
	if(navigator.onLine){
		var xhr = new XMLHttpRequest();
		xhr.open("PUT","http://localhost/sitesettings/getBadgeInfo.pt");
		xhr.send(editor.value);
		xhr.onload = function(){
			localStorage.lastSave = Date.now();
			savebutton.disabled = true;
		};
	}
}

// 如果检查服务器端是否有新版本的笔记
// 如果没有,则将当前版本保存到服务器端
function sync(){
	if(navigator.onLine){
		var xhr = new XMLHttpRequest();
		xhr.open("GET","http://localhost/sitesettings/getBadgeInfo.pt");
		xhr.send();
		xhr.onload = function(){
			var remoteModTime = 0;
			if(xhr.status == 200){
				var remoteModTime = xhr.getResponseHeader("Last-Modified");
				remoteModTime = new Date(remoteModTime).getTime();
			}
			if(remoteModTime > localStorage.lastModified){
				status("Newer note found on server.");
				var useit = confirm("There is a newer verion of the note\n"+
									 "on the server. Click Ok to use that version\n"+
									 "or click Cancel to continue editing this\n"+
									 "version and overwrite the server");
				var now = Date.now();
				if(useit){
					editor.value = localStorage.note = xhr.responseText;
					localStorage.lastSaved = now;
					status("Newest version downloaded");
				}else{
					status("Ignoring newer version of the note.");
				}
				localStorage.lastModified = now;
			}else{
				ststus("You are editing the current version of the note.");
			}
			if(localStorage.lastModified > localStorage.lastSaved){
				save();
			}
			editor.disabled = false; // 再次启用编辑器
			editor.focus(); // 将光标定位到编辑器中
		};
	}else{
		//离线状态下,不能同步
		status("Can't sync while offline");
		editor.disabled = false;
		editor.focus();
	}
}

note.appcache:

代码语言:javascript
复制
CACHE MANIFEST
#note v1.0

note.html
note.js

NETWORK:
note
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015年01月19日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、localStorage和sessionStorage
  • 二、Cookie
  • 三、应用程序缓存
  • 四、离线Web应用
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档