Safari在同一标签页中触发StorageEvent

12

我在Safari(版本13.1)中遇到了一个奇怪的问题。

使用案例:我正在在各个打开的选项卡之间同步数据。这是通过写入本地存储并侦听“存储”事件来实现的。

根据我的理解(以及MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/storage_event),当某些内容被写入本地存储且满足以下两个条件时,应触发存储事件:

  • 项目的值已更改
  • 此更改源自相同域,但不同文档(即其他选项卡/窗口)

换句话说:

  • 假设我有两个打开的选项卡(A和B)
  • 两者都侦听“存储”更改
  • 其中一个选项卡(A)向本地存储中写入一些内容
  • 只有另一个选项卡(B)应接收“存储”事件

在Chrome、Firefox和Opera中完全正常工作。但是在Safari中,它也会在同一选项卡中触发。

此代码将复制此问题(可在控制台中任何站点上使用):

window.addEventListener('storage', event => console.log(event));
window.localStorage.setItem('foo', 'bar');
  • 在Chrome/Firefox/Opera中不会记录任何内容(预期行为)
  • 在Safari中,将在同一窗口中记录存储事件

此外,该事件本身似乎没有足够的信息来识别是哪个标签触发了它。我正在考虑编写另一个带有每个打开的选项卡唯一密钥的辅助程序,并将其写入本地存储并监听其变化。但在我这样做之前,我想看看是否漏掉了什么。我知道有一些库可以向其他选项卡发送消息,但在像这样基本的事情上引入专用库让我有些犹豫。

问题:我是否漏掉了什么?是否有一种方法可以让Safari中的存储事件仅在从其他选项卡写入内容时触发?


2
我也在这个Safari版本上遇到了同样的问题。但在旧版Safari上无法重现此问题。 - Danteinus
1
谢谢您尝试这个!看起来这是一个 bug... 我在 Bugzilla 上找到了它:https://bugs.webkit.org/show_bug.cgi?id=210512。我想我会使用一个解决方法。*叹气* - Christian Heine
我也遇到了这个问题,在MacBook和最新的iPhone上使用Safari 15.5。 - lwdthe1
1个回答

7

这也会发生在IE11上,就像这里这里所描述的那样。解决方法是检查您当前的选项卡是否处于焦点状态,就像这里所述。

所以,在您的代码中:

function handler (event) {
  if (!document.hasFocus()) {
    // continue with your logic
  }
}
window.addEventListener('storage', handler);

我建议您处理IE问题(如果您的应用需要),如上面的答案所述。您可以通过检测浏览器并增强上述逻辑来解决此问题。


嗨,感谢您的回答。我一定会看看这个。与此同时,我写了一个小型的自用实用程序类,用于跟踪当前打开的窗口(主要是围绕加载/卸载/可见性更改事件构建)。尽管如此,我仍然认为整个行为是一个错误。 - Christian Heine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接