参考:《JavaScript 高级程序设计》(第3版)
扩展:
文章伊始,抛出两个面试问题:
sessionStorage
在多窗口之间是否能共享状态?
sessionStorage
数据存储在哪里?
答案请往下探索 ~~~
Web Storage 是 HTML5 规范中提出的,目的是客服 cookie 带来的限制,当数据存储在客户端时,无需持续的跟随请求发送回服务器。
Web Storage 规范早期包含 sessionStorage 和 globalStorage,后面修订版更改为 sessionStorage 和 localStorage。
1. Storage 类型
Storage 类型提供最大的存储空间来存储名值对字符串。(非字符串数据在存储之前会被转换成字符串)
Storage 的实例有以下几种方法、属性:
getItem(name) | 获取指定name对应的值 | FireFox 中没有实现 |
setItem(name,value) | 为指定的name设置一个对应值 | |
removeItem(name) | 删除由name指定的 名值 对 | 不建议使用delete来删除数据,避免兼容性等问题 |
clear() | 删除所有值 | |
key(index) | 获取index位置处的名字 | |
length | 获取Storage中存储了多少名值对 | 可以结合key和length来迭代存储的数据 |
remainingSpace | 获取还可以使用的存储空间字节数 | IE8 独有 |
2. sessionStorage
存储特定的某个会话的数据。
sessionStorage 会话数据特性:
- 不可跨越会话,浏览器关闭,数据被删除;
- 跨越浏览器刷新而存在(即同一页面,执行刷新,会话数据还在);
- 浏览器崩溃并重启之后,FireFox 和 WebKit 的会话数据仍存在,IE 不存在;
- 会话数据只能被最初给对象存储数据的页面访问,所以对多页面有限制;
- 在该标签或窗口打开一个新页面时会复制顶级浏览会话的上下文作为新会话的上下文;
- 只有在本页面中以新页签或窗口打开的同源页面会复制(
临时共享)
之前页面的sessionStorage;- 例如window.open("同源页面"),a标签打开同源页面等等。
- 当在前一个页面中继续进行sessionStorage写入时,新标签页不会再同步。
- 只有在本页面中以新页签或窗口打开的同源页面会复制(
浏览器写入 sessionStorage 数据方式:
FireFox 和 WebKit 是同步写入。即添加到存储空间的数据立即被提交。
IE 是异步写入。即设置数据和写入数据有一定时间间隔。
- IE8 中可以强制把数据立即写入磁盘
// 只适用于IE8
sessionStorage.begin(); // 调用begin方法,开始收集数据。
sessionStorage.name = "不头秃的码农";
sessionStorage.book = "JavaScript";
sessionStorage.commit(); // 调用commit后,立即被写入磁盘。
3. globalStorage
跨越会话存储信息。(实现于 FireFox2 ,在修订版 HTML5 中被 localStorage 取代)
globalStorage 不是 Storage 的实例,globalStorage["wrox.com"] 才是。
使用方法:指定可以访问该数据的域
// ==================== 保存数据 ====================
// 存储数据于wrox.com域名下
globalStorage["wrox.com"].name = "不头秃的码农";
// 存储的数据,所有域名都可以访问(危险)
globalStorage[""].name = "不头秃的码农";
// 如果事先不能确定域名,可使用location.host作为属性名比较安全。
globalStorage[location.host].name = "不头秃的码农";
// ==================== 获取数据 ====================
let name1 = globalStorage["wrox.com"].name;
let name2 = globalStorage[""].name;
let name3 = globalStorage[location.host].name;
同源限制,例如:
使用 http 协议在 wrox.com 中存储了数据,使用 https 访问 wrox.com 的页面,获取不到数据。
尺寸限制,因浏览器而异:
Chrome、Safari、IOS 版 Safari、Android 版 WebKit 限制是 2.5M,
IE8、Opera 限制是 5M。
若不使用 removeItem、delete、clear 等方法删除,也没清理浏览器缓存,存储在 globalStorage 上的数据会一直存在于磁盘上。
适用于:在客户端存储文档、或者保存用户偏好设置。
4. localStorage
4.1 简介
在修订过的 HTML5 规范中取代了 globalStorage,作为持久保存客户端的数据方案。
localStorage 相当于 globalStorage[location.host]。
localStorage 是 Storage 的实例。
// 使用方法存储数据
localStorage.setItem('name', '不头秃的码农');
// 使用属性存储数据
localStorage.book = 'JavaScript';
// 使用方法读取数据
let name = localStorage.getItem('name');
// 使用方法读取数据
let book = localStorage.book;
数据存储在磁盘上,可跨会话取用,可通过Storage方法删除或通过清除浏览器缓存删除。
同源限制:
要访问localStorage,页面必须来自同一域名、同一协议、同一端口号。
尺寸限制:
Chrome、Safari、IOS 版 Safari、Android 版 WebKit 限制是 2.5M,其他是 5M。
4.2 storage 事件
对Storage对象进行任何修改,都会触发storage事件。
这个事件的event对象有以下属性:
domain | 发生变化的存储空间域名 |
key | 设置或删除的键名 |
newValue | 如果是设置值,则是新值;如果是删除键,则是null |
oldValue | 键被更改之前的值 |
侦听storage事件:
一定要关注下面写的监听条件哦 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
/**
* 监听storage事件条件:
* 当不在同一标签页的同一页面localStorage变动时,会触发storage事件
* 即:两个标签页展示同一页面,B页面会监听到A页面localStorage发生的变动
*/
window.addEventListener("storage", function (e) {
console.log("监听到storage事件:", e);
});
localStorage.setItem("nameText", "不头秃的码农");
setTimeout(() => {
localStorage.removeItem("nameText");
}, 1000);