Web Storage 的目的是解决通过客户端存储不需要频繁发送回服务器的数据时使用 cookie 的问题。
Web Storage 主要有两个目标:
Web Storage 定义了两个对象: localStorage 和 sessionStorage。前者是永久存储机制,而后者是跨会话的存储机制。这两个浏览器存储 API 提供了在浏览器中不收页面刷新影响而存储数据的两种方式。
Storage 类型用于保存 名/值 对数据,直至存储空间上限(由浏览器决定)。Storage 的实例与其他对象一样,但增加了以下方法:
getItem()、removeItem(name) 和 setItem() 方法可以直接或间接通过 Storage 对象调用。因为每个数据项都作为属性存储在该对象上,所以可以使用点或括号操作符访问这些属性,统统同样的操作来设置值,也可以使用 delete 操作符来删除属性。
在修订的 HTML5 规范里,localStorage 对象取代了 globalStorage,作为在客户端持久存储数据的机制,要访问同一个 localStorage 对象,页面必须来自同一个域(子域不可以)、在想用的端口上使用相同的协议。
因为 localStorage 是 Storage 的实例,所以可以像使用 sessionStorage 一样使用 localStorage。具体示例:
// 使用方法存储数据
localStorage.setItem("moment", 777);
// 使用属性存储数据
localStorage.nickname = "moment";
// 使用方法获取数据
const name = localStorage.getItem("moment");
// 使用属性获得数据
const nickname = localStorage.nickname;
两种存储方法的区别在于,存储在 localStorage 中的数据会保留到通过 JavaScript 删除或者用户清除浏览器缓存。localStorage 数据不受页面刷新影响,也不会因关闭窗口,标签也或重新启动浏览器而丢失。
每当 Storage 对象发生变化时,都会在文档上触发 storage 事件,使用属性或者 setItem() 设置值、使用 delete 或 removeItem() 删除值,以及每次调用 clean() 时都会触发这个事件,这个事件的事件对象有如下四个属性:
可以使用如下代码监听 storage 事件:
window.addEventListener("storage", function (e) {
document.querySelector(".my-key").textContent = e.key;
});
对于 sessionStorage 和 localStorage 上的任何更改都会触发 storage 事件,但 storage 事件不会区分这两者。
注意:使用 localStorage 存储 token 也不是说百分百安全的,依然会存在一些问题和风险,如容易收到 XSS 攻击、不支持跨域共享等。因此,在使用 localStorage 存储令牌时,开发者需要采取适当的安全措施,如加密存储数据、定期更新令牌等,以确保令牌的安全性和有效性。
localStorage 是一直域限制的存储机制,通常只能在同一域名下的页面中访问。默认情况下,localStorage 的数据在不同域名或跨域的情况下是无法直接访问的。有几种方法可以实现跨域访问 localStorage 中的数据:
使用 postMessage 将数据从一个窗口传递到另一个窗口,并在目标窗口中将数据存储到 localStorage 中,实例代码如下:
// 发送消息到目标窗口
window.postMessage(
{ key: "token", value: "1233211234567" },
"https://liangzai.com"
);
在接收消息的窗口中:
// 监听消息事件
window.addEventListener("message", function (event) {
if (event.origin === "https://sourcedomain.com") {
// 存储数据到 LocalStorage
localStorage.setItem(event.data.key, event.data.value);
}
});
Cookie 和 LocalStorage 是两种用于在浏览器中存储数据的机制,它们在以下方面有一些区别:
Cookie 适合用于在客户端和服务器之间传递数据、跨域访问和设置过期时间,而 LocalStorage 适合用于在同一域名下的不同页面之间共享数据、存储大量数据和永久存储数据。选择使用哪种机制应根据具体的需求和使用场景来决定。