Chrome 的 localStorage 实现的错误?

IT技术 javascript html google-chrome
2021-03-05 10:55:08

关于这个问题,在 Chrome 8.0.552.224 中将函数绑定到 Storage 对象的更改事件时,我得到了一个奇怪的结果。

考试:

<!DOCTYPE html>
<html>
  <head>
    <title>Chrome localStorage Test</title>
    <script type="text/javascript" >

      var handle_storage = function () {
        alert('storage event');
      };

      window.addEventListener("storage", handle_storage, false);

    </script>
  </head>
  <body>
    <button id="add" onclick="localStorage.setItem('a','test')">Add</button>
    <button id="clear" onclick="localStorage.clear()">Clear</button>
  </body>
</html>
  • 在两个 Chrome 窗口中打开页面,一个窗口有两个选项卡,
  • 单击“添加”按钮

当我这样做时,我会在第二个选项卡和第二个窗口上显示一个警报框,但不在调用该事件的选项卡上(我点击了)。据我了解,我应该看到三个警报框(打开的每个选项卡一个)。

这是一个错误吗?有没有其他人得到这种行为?如果不是,你运行的是什么版本?还是我刚刚把这一切都弄错了?

2个回答

更新和最终结论

事实证明,规范实际上这是所需的行为,因此 IE9 的实现被破坏了

4.2 sessionStorage 属性

当setItem()的removeItem(),并明确()方法被调用的存储对象X ...如果这些方法做了,然后在每一个HTMLDocument的...... [是]与同一存储区域相关,其他比 x,必须触发存储事件....

正如我们所看到的,规范在明确说明这是指定的行为方面做得非常糟糕。这就是 Opera 10 的实现被破坏的原因,这很可能也是 IE9 的实现被破坏的原因。

我们从中学到什么?始终阅读规范的每一个单个、单词(特别是如果你正在实现这些东西......)。

旧答案

正如您所说,这里的基本行为是“在除当前页面之外的所有页面上调用”。

去年 7 月有一份旧的 Chrome错误报告

正如人们在那里读到的那样,Firefox 也有同样的“问题”。我已经用最新的 nightly 测试了这个,仍然像在 Chrome 中一样表现。

Opera 11 中的另一个测试表明,这一定是某种特定的行为,因为 Opera 11 做了完全相同的事情,但 Opera 10确实在所有窗口/选项卡上触发了事件。遗憾的是,Opera 11 的官方更新日志没有说明此行为的任何更改。

通读规范,没有任何内容说明这种行为。我唯一能找到的是:

当存储区域发生变化时会触发 storage 事件,如前两节所述(对于会话存储,对于本地存储)。

发生这种情况时,用户代理必须将任务排队以触发名称为 storage 的事件,该事件不会冒泡且不可取消,并且使用 StorageEvent 接口,在其 Document 对象具有一个受影响的 Storage 对象的每个 Window 对象上.

注意:这包括未完全激活的 Document 对象,但事件循环会忽略在这些对象上触发的事件,直到 Document 再次完全激活。

那么,注释是什么意思?

从另一个规范

当一个 Document 是其浏览上下文的活动文档,并且它的浏览上下文是顶级浏览上下文,或者该浏览上下文嵌套在其中的 Document 本身是完全活动的时,就说它是完全活动的。

没有意义吗?是的。它对我们有任何帮助吗?不。

所以我们(在 JavaScript 聊天室)戳#whatwg 看看这一切是关于什么的,到目前为止还没有回应。收到任何回复后,我会立即更新我的答案。

暂时总结

Firefox、Chrome、Safari 和 Opera 具有完全相同的行为。也就是说,它们不会在为 localStorage 提供机会的选项卡/窗口上触发。

但是 IE9 Beta 的行为类似于 Opera 10,因此它会在所有选项卡/窗口上触发

由于 localStorage 规范的作者在 Google 从事研发工作,我几乎不怀疑 Chrome 会犯这个错误。由于在 Bugzilla 上没有错误,Opera 改变了 11 中的行为,这似乎是它应该工作的方式。仍然没有答案为什么它会以这种方式工作以及为什么 IE9 的行为不同,但我们仍在等待#whatwg 的响应。

关于为什么以这种方式指定这种行为的任何更新?我没有看到他们通过不为当前选项卡发出事件来解决什么问题。
2021-04-28 10:55:08
您可以在同一个选项卡中覆盖 setItem 和 fire 事件吗?使用 localStorage 绑定来获取本地表单和 dom 的数据似乎是合乎逻辑的。绑定 localStorage 以更新页面上的元素 - 然后创建 socketio 或 websocket 事件以更新 localStorage,从而实现无缝实时体验...
2021-05-09 10:55:08
这仍然是 IE10 中的一个问题,所以我在这里向微软提出了这个问题:connect.microsoft.com/IE/feedback/details/774798/...
2021-05-11 10:55:08
我也想知道这件事。
2021-05-18 10:55:08

Ivo Wetzel 对出了什么问题的回答是正确的。

我遇到了同样的问题,但设法通过在启动存储更改的选项卡中手动创建和触发 StorageEvent 来解决规范中的这个限制(请参阅StorageEvent#initStorageEvent)。