【问题标题】:localStorage in win8.1 IE11 does not synchronizewin8.1 IE11中localStorage不同步
【发布时间】:2014-07-27 10:41:45
【问题描述】:

我们有两个页面“/read”和“/write”。页面“/write”每秒用当前时间更新localStorage:

setInterval(function(){
    var time = (new Date()).getTime();
    localStorage.setItem("time", time);
    console.log("set", time);
},1000);

页面“/read”读取相同的存储:

setInterval(function(){
    var time = localStorage.getItem("time");
    console.log("get", time);
},1000);

人们会认为“/read”页面应该显示由另一个页面写入 localStorage 的相同值。但是在 Win8.1 上的 IE11 中,这被打破了。页面“/read”从存储中读取一些旧值,然后它会显示相同的值(就好像它使用缓存作为本地存储一样)。有什么想法吗?

附:两个页面都在同一个域上(实时示例 - read write

【问题讨论】:

  • 它在我的情况下工作正常。我已经检查过 IE11。它每秒打印更新的值。
  • Win8.1 上的 IE11?我问它是因为在 win7 中它工作正常
  • 我有同样的问题,在 Win8.1 上的 IE9 中它也没有按预期工作。
  • 在下面查看我的“答案”。它似乎也不适用于 win10 中的 Edge

标签: javascript html internet-explorer local-storage internet-explorer-11


【解决方案1】:

与其说是答案,不如说是进一步调查。使用下面的页面,可以通过托管在 Web 服务器上并在不同的选项卡中打开它来轻松测试此问题。然后点击一个标签中的按钮。

<!DOCTYPE html>
<head>
    <title>LocalStorage Test</title>
</head>
<body>
<button onclick="setLocalStorageValue()">Set Time</button>

<script>
    setInterval(function () {
        console.log(window.localStorage.getItem("test_key"));
    }, 1000);

    function setLocalStorageValue () {
        window.localStorage.setItem("test_key", new Date().getTime());
    }
</script>
</body>
</html>

无论操作系统如何,Chrome/Firefox/Safari 中的结果都是可以预测的。 它们表明 localStorage 在来自同一 Origin 的页面之间共享。

在 Windows 7 上的 IE11 上,也给出了相同的结果。

根据我的阅读,这似乎符合规范,此处为第 3 点 https://html.spec.whatwg.org/multipage/webstorage.html#the-localstorage-attribute

但是……

  • Windows 8.1 上的 IE 11 将为同一来源展示单独的 localStorage 区域。

  • Windows 10 (10162) 上的 Microsoft Edge 也有同样的问题。 IE11 在 Windows 7 上显示“正确”行为这一事实表明操作系统是问题所在?

【讨论】:

  • 我也调查了这个问题,不幸的是,在两个窗口中的任何一个中使用 localStorage.setItem 方法成功更新了本地存储文件 (%userprofile%\AppData\Local\Microsoft\Internet Explorer\DOMStore \[RandomString]\[Domain].xml),localStorage.getItem 方法确实始终从文件中获取最新数据。在 8.1\IE11 上运行。
【解决方案2】:

似乎IE11/Windows 8下的localStorage.GetItem方法不可靠,可能会取回之前的值。但这可以通过在检索值之前立即调用 localStorage.SetItem 方法来解决。

我设法使用 muttonUp 的代码复制了该问题,然后进行了以下更改以使两个窗口相互通信:

<!DOCTYPE html>
<head>
    <title>LocalStorage Test</title>
</head>
<body>
<button onclick="setLocalStorageValue()">Set Time</button>

<script>
    setInterval(function () {
        window.localStorage.setItem("unused_key",null);
        console.log(window.localStorage.getItem("test_key"));
    }, 1000);

    function setLocalStorageValue () {
        console.log("Button clicked - setting time");
        window.localStorage.setItem("test_key", new Date().getTime());
    }
</script>
</body>
</html>

这是输出:

此解决方法在我的场景中很有用,因为我只是不频繁地从 localStorage 中检索值并且只存储少量数据。由于 setItem 方法调用数量的增加可能会导致性能开销,因此在使用此解决方法之前,我可能会仔细考虑进出 localStorage 的流量。

【讨论】:

  • 很好的解决方法!所以 IE11 必须从底层操作系统请求值,而 win7 对每个 getItem 执行新的查找,但 Win8 和 Win10 不会。或者他们只是在 win7 和 Win8 之间更改了 IE11 的更改部分.....我个人希望他们现在已经解决了这个问题。
  • 谢谢 - 你提供的很好的例子 :-) 问题正在被跟踪,但(通常!)没有任何即将修复的迹象:developer.microsoft.com/en-us/microsoft-edge/platform/issues/…
  • 这对我不起作用,因为我有一个存储事件想要读取其他选项卡上的本地存储,如果我在处理事件时更改 localStorage,我会触发另一个事件这将是一个无限循环:D
  • @behzad 您可以在setTimeout(...) 中执行此操作。 ;)
【解决方案3】:

我在 Win 10 上找到了解决此问题的方法。如果您在代码中处理 window.onstorage 事件,则 localStorage 将为所有打开的选项卡刷新。 像这样简单的东西对我有用:

window.onstorage = function(e){
    //Leave this empty
    //or add code to handle
    //the event
};

我还没有彻底测试过这段代码,所以在任何生产应用程序中使用这种方法之前,请先测试一下。

希望这会有所帮助!

【讨论】:

  • edge v41 上同样的问题,可以确认这解决了问题。
【解决方案4】:

我的解决方案 - 角度应用程序:

 @HostListener('window:storage', ['$event'])

 testWindowStorage(event: StorageEvent) {

     if (event.key === 'xxx' && event.newValue !== event.oldValue 
         && event.newValue !== event.oldValue)) {

      //do your business
     }
 }

【讨论】:

    猜你喜欢
    • 2015-05-13
    • 2014-11-15
    • 2020-12-25
    • 2015-10-10
    • 1970-01-01
    • 2017-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多