Javascript Chrome 的 localStorage 实现有问题吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4679023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bug with Chrome's localStorage implementation?
提问by David Glenn
Further to this question, I'm getting a curious result when binding a function to the change event of the Storage object in Chrome 8.0.552.224.
关于这个问题,在 Chrome 8.0.552.224 中将函数绑定到 Storage 对象的更改事件时,我得到了一个奇怪的结果。
The test:
考试:
<!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>
- Open up the page in two Chrome windows, one window with two tabs,
- Click the 'Add' button
- 在两个 Chrome 窗口中打开页面,一个窗口有两个选项卡,
- 单击“添加”按钮
When I do this I get an alert box displayed on on the second tab and on the second window but not on the tab that invoked the event (the I clicked on). As I understand it I should see three alert boxes (one for each tab opened).
当我这样做时,我会在第二个选项卡和第二个窗口上显示一个警报框,但不在调用该事件的选项卡上(我点击了)。据我了解,我应该看到三个警报框(打开的每个选项卡一个)。
Is this a bug? Is anyone else getting this behaviour? If not what version are you running? Or have I just got this all completely wrong?
这是一个错误吗?有没有其他人得到这种行为?如果不是,你运行的是什么版本?或者我刚刚把这一切都弄错了?
回答by Ivo Wetzel
Update and final conlusion
更新和最终结论
It turns out that the spec actually saysthat this is the desired behavior, therefore IE9's implementation is broken.
事实证明,规范实际上说这是所需的行为,因此 IE9 的实现被破坏了。
4.2 The sessionStorage attribute
When the setItem(), removeItem(), and clear() methods are called on a Storage object x... if the methods did something, then in every HTMLDocument ... [that is] associated with the same storage area, other than x, a storage event must be fired....
4.2 sessionStorage 属性
当在 Storage 对象x上调用 setItem()、removeItem() 和 clear() 方法时……如果这些方法做了某事,那么在每个 HTMLDocument 中……[即] 与相同的存储区域相关联,其他比 x,必须触发存储事件....
So as we can see, the spec does do a really bad job at making it clear, that this is the specified behavior. That was the reason why Opera 10's implementation was broken and it's most likely also the reason why IE9's implementation is broken.
正如我们所看到的,规范在明确说明这是指定的行为方面做得非常糟糕。这就是 Opera 10 的实现被破坏的原因,这很可能也是 IE9 的实现被破坏的原因。
What do we learn from that? Always read every, single, word of the specification (especially if you're implementing the stuff...).
我们从中学到什么?始终阅读规范的每一个,单个,单词(特别是如果你正在实现这些东西......)。
Old answer
旧答案
As you said the basic behavior here is "Invoke on all but the current page".
正如您所说,这里的基本行为是“在除当前页面之外的所有页面上调用”。
There's an old Chrome Bug Reportfrom last July.
去年 7 月有一份旧的 Chrome错误报告。
As one can read there, Firefox has the same "issue". I've tested this with the latest nightly, still behaves the same way like in Chrome.
正如人们可以在那里阅读的那样,Firefox 也有同样的“问题”。我已经用最新的每晚对此进行了测试,其行为方式仍与 Chrome 中相同。
Another test in Opera 11 shows that this must be some kind spec'ed behavior, since Opera 11 does the exact same thing but Opera 10 didfire events on all windows / tabs. Sadly the official changelogs for Opera 11 do not state any change for this behavior.
Opera 11 中的另一个测试表明,这一定是某种特定的行为,因为 Opera 11 做了完全相同的事情,但 Opera 10确实在所有窗口/选项卡上触发了事件。遗憾的是,Opera 11 的官方更新日志没有说明此行为的任何更改。
Reading through the specification, nothing there states this behavior. The only thing I could find is:
通读规范,没有任何内容说明这种行为。我唯一能找到的是:
The storage event is fired when a storage area changes, as described in the previous two sections (for session storage, for local storage).
When this happens, the user agent must queue a task to fire an event with the name storage, which does not bubble and is not cancelable, and which uses the StorageEvent interface, at each Window object whose Document object has a Storage object that is affected.
Note: This includes Document objects that are not fully active, but events fired on those are ignored by the event loop until the Document becomes fully active again.
storage 事件在存储区域发生变化时触发,如前两节所述(对于会话存储,对于本地存储)。
发生这种情况时,用户代理必须将任务排队以触发名称为 storage 的事件,该事件不会冒泡且不可取消,并且使用 StorageEvent 接口,在其 Document 对象具有受影响的 Storage 对象的每个 Window 对象上.
注意:这包括未完全激活的 Document 对象,但事件循环会忽略在这些对象上触发的事件,直到 Document 再次完全激活。
Well, what does the Note mean?
那么,注释是什么意思?
From another specification:
从另一个规范:
A Document is said to be fully active when it is the active document of its browsing context, and either its browsing context is a top-level browsing context, or the Document through which that browsing context is nested is itself fully active.
当一个 Document 是其浏览上下文的活动文档,并且它的浏览上下文是顶级浏览上下文,或者该浏览上下文嵌套在其中的 Document 本身是完全活动的时,就说它是完全活动的。
Doesn't make sense? Yes. Does it help us in any way? No.
没有意义吗?是的。它对我们有任何帮助吗?不。
So we (in the JavaScript Chatroom) poked on #whatwg to see what all of this is about, so far there has been no response. I'll update my answer as soon as we get any response.
所以我们(在 JavaScript 聊天室)戳#whatwg 看看这一切是关于什么的,到目前为止还没有回应。收到任何回复后,我会立即更新我的答案。
To conclude for now
暂时总结
Firefox, Chrome, Safari and Opera have the exact same behavior. That is, they do not fire on the tab / window that made the chance to localStorage.
Firefox、Chrome、Safari 和 Opera 具有完全相同的行为。也就是说,它们不会在为 localStorage 提供机会的选项卡/窗口上触发。
But IE9 Beta behaves like Opera 10, so it fires on alltabs / windows.
但是 IE9 Beta 的行为类似于 Opera 10,因此它会在所有选项卡/窗口上触发。
Since the author of the localStorage spec works at Google in R&D, I hardly doubt Chrome would get this wrong. And since there are no Bugs on this over at Bugzilla and Opera changed the behavior in 11, it seems that this is the way it should work. Still no answer why it works this way and why IE9 behaves differently, but we're still waiting for a response from #whatwg.
由于 localStorage 规范的作者在 Google 从事研发工作,我几乎不怀疑 Chrome 会犯这个错误。由于在 Bugzilla 上没有错误,Opera 改变了 11 中的行为,这似乎是它应该工作的方式。仍然没有答案为什么它会以这种方式工作以及为什么 IE9 的行为不同,但我们仍在等待#whatwg 的响应。
回答by Jamie Cramb
Ivo Wetzel's answer for what is going wrong is correct.
Ivo Wetzel 对出了什么问题的回答是正确的。
I was having the same problem but managed to work around this limitation in the spec by manually creating and firing a StorageEvent in the tab that initiated the storage change (see StorageEvent#initStorageEvent).
我遇到了同样的问题,但设法通过在启动存储更改的选项卡中手动创建和触发 StorageEvent 来解决规范中的这个限制(请参阅StorageEvent#initStorageEvent)。