# 浏览器存储-Storage

# Storage

Web 存储对象 localStorage 和 sessionStorage 允许我们在浏览器上保存键/值对。

它们有趣的是,在页面刷新后(对于 sessionStorage)甚至浏览器完全重启(对于 localStorage)后,数据仍然保留在浏览器中。

# localStorage

localStorage 最主要的特点是:

  • 在同源的所有标签页和窗口之间共享数据。
  • 数据不会过期。它在浏览器重启甚至系统重启后仍然存在。

localStorage.setItem("test", 1);

重启浏览器之后

console.log(localStorage.getItem("test")); // 1

我们还可以像使用一个普通对象那样,读取/设置键,像这样:

// 设置 key
localStorage.test = 2;
// 获取 key
console.log(localStorage.test);
// 删除 key
delete localStorage.test;

WARNING

这是历史原因造成的,并且大多数情况下都可行,但通常不建议这样做

# sessionStorage

sessionStorage 对象的使用频率比 localStorage 对象低得多。

属性和方法是相同的,但是它有更多的限制:

  • sessionStorage 的数据只存在于当前浏览器标签页。
    • 具有相同页面的另一个标签页中将会有不同的存储。
    • 但是,它在同一标签页下的 iframe 之间是共享的(假如它们来自相同的源)。
  • 数据在页面刷新后仍然保留,但在关闭/重新打开浏览器标签页后不会被保留。

sessionStorage 不仅绑定到源,还绑定在同一浏览器标签页。因此,sessionStorage 很少被使用。

# 仅字符串

请注意,键和值都必须是字符串。

如果是任何其他类型,例数字或对象,它会被自动转换为字符串。

localStorage.user = { name: "John" };
alert(localStorage.user); // [object Object]
let obj = { name: "John" };
localStorage.setItem("test", JSON.stringify(obj));
let obj2 = JSON.parse(localStorage.getItem("test"));

# storage 事件

当 localStorage 或 sessionStorage 中的数据更新后,storage 事件就会触发

// 在其他文档对同一存储进行更新时触发
window.onstorage = (event) => {
  // 等同于 window.addEventListener('storage', () => {
  if (event.key != "now") return;
  alert(event.key + ":" + event.newValue + " at " + event.url);
};

localStorage.setItem("now", Date.now());

不同窗口

storage 事件不会在同一个窗口内触发

现代浏览器还支持 Broadcast channel API,这是用于同源窗口之间通信的特殊 API,它的功能更全,但被支持的情况不好。有一些库基于 localStorage 来 polyfill 该 API,使其可以用在任何地方。