Web 存储对象localStorage并sessionStorage允许在浏览器中保存键/值对

Web 存储对象localStoragesessionStorage允许在浏览器中保存键/值对。

它们的有趣之处在于,数据在页面刷新(对于sessionStorage)甚至完全浏览器重新启动(对于localStorage)后仍然存在。我们很快就会看到。

我们已经有了 cookie。为什么要附加对象?

  • 与 cookie 不同,Web 存储对象不会随每个请求一起发送到服务器。正因为如此,我们可以存储更多。大多数浏览器允许至少 2 兆字节(或更多)的数据,并具有配置它的设置。
  • 与 cookie 不同的是,服务器不能通过 HTTP 标头操作存储对象。一切都在 JavaScript 中完成。
  • 存储绑定到源(域/协议/端口三元组)。即不同的协议或子域推断出不同的存储对象,它们不能相互访问数据。

两个存储对象都提供相同的方法和属性:

  • setItem(key, value) – 存储键/值对。
  • getItem(key) – 按键获取值。
  • removeItem(key) – 删除键及其值。
  • clear() – 删除所有内容。
  • key(index) – 获得给定位置的钥匙。
  • length – 存储项目的数量。

正如你所看到的,它就像一个Map集合(setItem/getItem/removeItem),但也允许通过索引访问key(index)

让我们看看它是如何工作的。

本地存储演示

的主要特点localStorage是:

  • 在同一来源的所有选项卡和窗口之间共享。
  • 数据不会过期。它在浏览器重新启动甚至操作系统重新启动后仍然存在。

例如,如果您运行此代码……

localStorage.setItem('test', 1);

…然后关闭/打开浏览器或者只是在不同的窗口中打开同一个页面,然后你可以像这样得到它:

alert( localStorage.getItem('test') ); // 1

我们只需要在同一个源(域/端口/协议)上,url 路径可以不同。

localStorage在具有相同来源的所有窗口之间共享,因此如果我们将数据设置在一个窗口中,则更改将在另一个窗口中可见。

类对象访问

我们还可以使用普通的对象方式来获取/设置键,如下所示:

// set key
localStorage.test = 2;

// get key
alert( localStorage.test ); // 2

// remove key
delete localStorage.test;

由于历史原因,这是允许的,并且大多数情况下都有效,但通常不推荐,因为:

  1. 如果密钥是用户生成的,它可以是任何东西,比如lengthor toString,或者localStorage. 在这种情况下getItem/setItem工作正常,而类似对象的访问失败:

    let key = 'length';
    localStorage[key] = 5; // Error, can't assign length
  2. 有一个storage事件,它在我们修改数据时触发。对于类似对象的访问,该事件不会发生。我们将在本章后面看到。

循环键

正如我们所见,这些方法提供了“按键获取/设置/删除”功能。但是如何获取所有保存的值或键?

不幸的是,存储对象是不可迭代的。

一种方法是将它们作为数组循环:

for(let i=0; i<localStorage.length; i++) {
  let key = localStorage.key(i);
  alert(`${key}: ${localStorage.getItem(key)}`);
}

另一种方法是使用for key in localStorage循环,就像我们使用常规对象一样。

它遍历键,但也输出一些我们不需要的内置字段:

// bad try
for(let key in localStorage) {
  alert(key); // shows getItem, setItem and other built-in stuff
}

…所以我们需要通过hasOwnProperty检查过滤原型中的字段:

for(let key in localStorage) {
  if (!localStorage.hasOwnProperty(key)) {
    continue; // skip keys like "setItem", "getItem" etc
  }
  alert(`${key}: ${localStorage.getItem(key)}`);
}

…或者只是获取“自己的”键,Object.keys然后在需要时循环它们:

let keys = Object.keys(localStorage);
for(let key of keys) {
  alert(`${key}: ${localStorage.getItem(key)}`);
}

后者有效,因为Object.keys只返回属于对象的键,忽略原型。

仅限字符串

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

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

localStorage.user = {name: "John"};
alert(localStorage.user); // [object Object]

我们可以JSON用来存储对象:

localStorage.user = JSON.stringify({name: "John"});

// sometime later
let user = JSON.parse( localStorage.user );
alert( user.name ); // John

也可以对整个存储对象进行字符串化,例如用于调试目的:

// added formatting options to JSON.stringify to make the object look nicer
alert( JSON.stringify(localStorage, null, 2) );

会话存储

sessionStorage对象的使用频率远低于localStorage.

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

  • sessionStorage仅存在于当前浏览器选项卡中 。
    • 具有相同页面的另一个选项卡将具有不同的存储空间。
    • 但它在同一选项卡中的 iframe 之间共享(假设它们来自同一来源)。
  • 数据在页面刷新后仍然存在,但不会关闭/打开选项卡。

让我们看看实际情况。

运行此代码...

sessionStorage.setItem('test', 1);

…然后刷新页面。现在您仍然可以获取数据:

alert( sessionStorage.getItem('test') ); // after refresh: 1

…但是如果您在另一个选项卡中打开相同的页面,然后在那里再试一次,上面的代码会返回null,意思是“没有找到”。

这正是因为sessionStorage不仅绑定到源,还绑定到浏览器选项卡。因此,sessionStorage谨慎使用。

存储事件

当数据在localStorageor中更新时sessionStorage存储事件触发,具有以下属性:

  • key– 被改变的键(null如果.clear()被调用)。
  • oldValue– 旧值(null如果键是新添加的)。
  • newValue– 新值(null如果键被删除)。
  • url – 发生更新的文档的 url。
  • storageArea–更新发生的对象localStorage或对象。sessionStorage

重要的是:该事件会在所有window可访问存储的对象上触发,但导致它的对象除外。

让我们详细说明。

想象一下,您有两个窗口,每个窗口都有相同的站点。localStorage他们之间也是如此。

您可能希望在两个浏览器窗口中打开此页面以测试下面的代码。

如果两个窗口都在监听window.onstorage,那么每个窗口都会对另一个窗口中发生的更新做出反应。

// triggers on updates made to the same storage from other documents
window.onstorage = event => { // can also use window.addEventListener('storage', event => {
  if (event.key != 'now') return;
  alert(event.key + ':' + event.newValue + " at " + event.url);
};

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

请注意,该事件还包含:event.url– 更新数据的文档的 url。

此外,event.storageArea包含存储对象 - 和 的事件相同sessionStoragelocalStorage因此event.storageArea引用已修改的事件。我们甚至可能想在其中设置一些东西,以“响应”变化。

这允许来自同一来源的不同窗口交换消息。

现代浏览器也支持广播频道API,这是同源窗口间通信的特殊API,功能更全,但支持较少。有一些库基于 填充了该 API,localStorage使其在任何地方都可用。

概括

Web 存储对象localStoragesessionStorage允许在浏览器中存储键/值。

  • 两者都key必须value是字符串。
  • 限制为 5mb+,取决于浏览器。
  • 它们不会过期。
  • 数据绑定到源(域/端口/协议)。
localStoragesessionStorage
在具有相同来源的所有选项卡和窗口之间共享在浏览器选项卡中可见,包括来自同一来源的 iframe
在浏览器重启后幸存下来存活页面刷新(但不是标签关闭)

接口:

  • setItem(key, value) – 存储键/值对。
  • getItem(key) – 按键获取值。
  • removeItem(key) – 删除键及其值。
  • clear() – 删除所有内容。
  • key(index)– 获取钥匙号码index
  • length – 存储项目的数量。
  • 用于Object.keys获取所有密钥。
  • 我们将键作为对象属性访问,在这种情况storage下不会触发事件。

存储事件:

  • 触发setItemremoveItem,clear调用。
  • 包含有关操作 ( key/oldValue/newValue)、文档url和存储对象的所有数据storageArea
  • 触发所有window有权访问存储的对象,但生成它的对象除外(在选项卡内 用于sessionStorage,全局用于localStorage)。

任务

创建一个textarea在每次更改时“自动保存”其值的字段。

因此,如果用户不小心关闭了页面,然后再次打开它,他会在原处找到未完成的输入。

<!doctype html>
<textarea style="width:200px; height: 60px;" id="area" placeholder="Write here"></textarea>
<br>
<button onclick="localStorage.removeItem('area');area.value=''">Clear</button>
<script>
    area.value = localStorage.getItem('area');
    area.oninput = () => {
      localStorage.setItem('area', area.value)
    };
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值