本地数据存储
HTTP Cookie
cookie 是服务器保存在浏览器的一小段文本信息,浏览器每次向服务器发出请求,会携带 cookie 信息到服务器。cookie 常用于在本地记录用户信息,利用 cookie 可以改进用户体验。
写入 cookie
cookie 字符串是一组名值对,名称和值之间以等号相连,名值对之间使用分号进行分割。值中不能包含分号,逗号,空格。如果包含特殊字符,应该使用 escape() 进行编码,在读取 cookie 时才使用 unescape() 函数进行解码。
- cookie 信息字符串,包含一个名值对,默认为空。
- cookie 有效期,包含一个 GMT 格式字符串,默认为当前会话期,即关闭浏览器时,cookie 信息就会过期。
- cookie 有效路径,默认为 cookie 所在页面目录及其子目录。
- cookie 有效域,默认为设置 cookie 的页面所在的域。
- cookie 安全性,默认为不采用安全加密措施进行传递。
使用 document.cookie 可以读写 cookie 字符串信息。
// 存储 cookie 信息
var d = new Date();
d = d.toString();
console.log(d); // Thu Aug 12 2021 13:35:02 GMT+0800 (中国标准时间)
d = "date=" + escape(d);
console.log(d);
document.cookie = d;
如果要长久保存 cookie 信息, 可以设置 expires 属性,把字符串 “expires=date” 附加到 cookie 字符串后面,如下:
name = value;expires = date;
/*
date 为格林威治日期时间(GMT),格式为 Sun, 30 Apr 2017 00:00:00 UTC
使用 Date.toGMTString() 方法可以快速把事件转换为 GMT 格式。
*/
下面创建一个有效期为一个月的 cookie 信息
var d = new Date();
d.setMonth(d.getMonth() + 1); // 提取月份加 1,然后重新设置当前日期对象
d = "date=" + escape(d) + ";expires=" + d.toGMTString();
document.cookie = d;
cookie 信息是有 域 和 路径限制的,默认情况下,仅在当前页面路径内有效。
可以使用 cookie 的 path 和 domain 属性重设可见路径和作用域。其中 path 属性包含了与 cookie 信息相关联的有效路径,domain 属性定义了 cookie 信息的有效作用域。用法如下:
name=value;expires=date;domain=domain;path=path;
很多网站可能包含很多子域名,如:
默认情况下,cookie 只能在本域中访问,通过设置 cookie 的 domain 属性修改域的范围,例如在 http://www.baidu.com/index.html 中设置 cookie 的 domain 属性为 domain = tieba.baidu.com,就可以在 http://tieba.baidu.com 域下访问该 cookie。如果设置 cookie 的 domain = baidu.com,则所有子域名都可以访问。
// 把写入 cookie 信息的实现代码进行封装
/**
* @param {cookie 名称} name
* @param {cookie 值} value
* @param {有效天数} expires
* @param {有效路径} path
* @param {域} domain
* @param {安全性设置, 是否加密传输} secure
*/
function setCookie(name, value, expires, path, domain, secure) {
var today = new Date();
// today.getTime() 时间戳
today.setTime(today.getTime()); // 设置现在时间
if (expires) {
expires = expires * 1000 * 60 * 60 * 24; // 转换为毫秒数
}
var expires_date = new Date(today.getTime() + expires); // 新建有效期时间对象
document.cookie = name + "=" + escape(value) + (expires ? ";expires=" + expires_date.toGMTString() : "") + (path ? ";path=" + path : "") + (domain ? ";domain=" + domain : "") + (secure ? ";secure" : "");
}
读取 cookie
// 将 cookie 字符串转换为对象类型
function getCookie() {
var a = document.cookie.split(";");
var o = {};
for (var i = 0; i < a.length; i++) {
var v = a[i].split("=");
o[v[0]] = v[1];
}
return o;
}
// 指定 cookie 名,获取单个 cookie
// 多条 cookie
// "date=Sun%20Sep%2012%202021%2014%3A18%3A53%20GMT+0800%20%28%u4E2D%u56FD%u6807%u51C6%u65F6%u95F4%29; test1=1; test2=2"
function getCookie(name) {
var start = document.cookie.indexOf(name + "="); // 提取与 cookie 名相同的字符串索引
var len = start + name.length + 1; // 计算值的索引位置
if (!start && name != document.cookie.substring(0, name.length)) { // 没有返回 null
return null;
}
if (start == -1) return null;
var end = document.cookie.indexOf(";", len);
if (end == -1) end = document.cookie.length;
return unescape(document.cookie.substring(len, end))
}
console.log(getCookie('test1')); // 1
修改和删除 cooKie
function deleteCookie(name, path, domain) {
if (getCookie(name)) {
document.cookie = name + "=" + (path ? ";path=" + path : "") + (domain ? ";domain=" + domain : "") + ";expires=Thu, 01-Jan-1970 00:00:00 GMT";
}
}
deleteCookie('test1');
附加 cookie
浏览器对 cookie 信息有个数限制的,为了避免这个限制,可以把多条信息都保存在一个 cookie 中。
实现方式:
name=subName1:subValue1,subName2:subValue2,subName3:subValue3...
下面演示如何在 cookie 中存储更多信息:
var d = new Date();
d.setMonth(d.getMonth() + 1);
d = d.toGMTString();
var a = "name:a,age:20,addr:beijing";
var c = "user=" + escape(a);
c += (";expires=" + d);
document.cookie = c;
读取 cookie:
function getSubCookie()
{
var a = document.cookie.split(";");
var o ={};
for (var i = 0; i < a.length; i ++ ) {
a[i] && (a[i] = a[i].replace(/^\s+|\s+$/, ""));
var b = a[i].split("=");
var c = b[1];
c && (c = c.replace(/^\s+|\s+$/, ""));
c = unescape(c);
if( ! /\,/gi.test(c)){
o[b[0]] = b[1];
} else {
var d = c.split(",");
for (var j = 0; j < d.length; j ++ )
{
var e = d[j].split(":");
o[e[0]] = e[1];
}
}
}
return o;
}
Http-Only Cookie
设置 cookie 的时候,如果服务器加上了 HttpOnly 属性,则这个 cookie 无法被 JS 读取(即 document.cookie 不会返回这个 cooKie 的值),只用于向服务器发送。
Web Storage
- localStorage: 用于持久化的本地存储,除非主动删除;否则数据永远不会过期。
- sessionStorage: 用于存储本地会话(session)数据,这些数据只在同一个会话周期内访问,会话结束即被销毁。
遍历
var storage = window.localStorage;
for(var i = 0; len = storage.length; i < len; i++) {
var key = storage.key(i);
var value = storage.getItem(key);
console.log(key + "=" + value);
}
监测事件
Web Storage 定义的 storage 事件,当键值改变或者调用 clear() 方法的时候,将触发 storage 事件。
监听本地存储,当发生值变动时,及时进行提示:
if(window.addEventListener) {
window.addEventListener("storage", handle_storage, false);
} else if(window.attachEvent) {
window.attachEvent('onstorage', handle_storage);
}
function handle_storage(e) {
var logged = "key:" + e.key + ", newValue:" + e.newValue + ", oldValue:" + e.oldValue + ", url:" + e.url + ", storageArea:" + e.storageArea;
console.log(logged);
}