JavaScript的; 相同来源的标签/窗口之间的通信

我有两个窗口:窗口A和窗口B.

  • 窗口A和窗口B具有相同的域
  • 窗口A和窗口B没有任何父窗口。

问题:

  1. 窗口A是否有可能获得窗口B的引用?
  2. 什么是最优雅的方式使窗口A通知窗口B?
    (包括新的HTML5规范)

两种方式我知道这样做:

  • 通过服务器发送消息:窗口B定期询问服务器,如果窗口A已经通知了某事
  • 通过本地数据(HTML5)进行消息传递:当窗口A想要通知某些内容更改本地数据时,窗口B会定期检查本地数据是否有任何更改。

但是这两种方式并不那么优雅。
例如,获得窗口B的引用并使用window.postMessage()(HTML5)

最终的目标是做一些类似facebook的地方,如果你打开4个facebook标签并且在一个标签上聊天,那么在每个facebook标签中聊天都是最新的,这个标签是整洁的!

我坚持使用localStorage问题中提到的共享本地数据解决scheme。 这似乎是可靠性,性能和浏览器兼容性方面的最佳解决scheme。

localStorage在所有现代浏览器中实现。

其他选项卡更改localStorage时, storage事件触发。 这对通信目的来说非常方便。

参考可以在这里find:
Webstorage
Webstorage – 存储事件

BroadcastChannel标准允许这样做。 现在它在Firefox和Chrome( caniuse , mdn )中实现:

 // tab 1 var ch = new BroadcastChannel('test'); ch.postMessage('some data'); // tab 2 var ch = new BroadcastChannel('test'); ch.addEventListener('message', function (e) { console.log('Message:', e.data); }); 

SharedWorker是WHATWG / HTML5规范,用于可以在选项卡之间进行通信的常用过程。

你说过你的:

最大的目标就是制作一些类似于Facebook的东西,如果你打开4个Facebook标签页,并且在一个标签页上聊天,聊天function就会在每个Facebook标签页上实现,而且整洁!

这应该作为你的devise的副产品,查询模型(可能是服务器)更新聊天的意见,而不是你必须devise交叉视图通信。 除非你处理大量的数据传输,为什么要担心呢? 看起来似乎会让事情变得复杂而没有巨大的收益。

几年前,我发现,如果我使用现有窗口的名称和空白URL做了window.open ,我得到了对现有窗口的引用(这种行为甚至logging在MDC上, 对MSDN文档的评论表明它可以工作IE以及)。 但那是几年前,我不知道当今世界对它的支持有多普遍,当然,除非你所有的窗口都包含一个用于通信的命名的iframe ,否则你将不会有窗口名称,唯一命名的通过服务器端代码,然后通过服务器端代码传递给其他窗口…(可怕的想法:这实际上是可行的。将与当前login帐户相关的“当前”窗口名称存储在表中,给列表的任何新窗口创buildlogin到该帐户,剔除旧的非活动条目,但如果列表稍微过时,你会打开新窗口时,search其他人…我敢打赌,支持是如果从浏览器到浏览器。)

除了即将推出的SharedWorker ,您还可以使用跨文档消息传递 ,这得到了更广泛的支持 。 在这种情况下,必须有一个主窗口负责用window.open打开所有其他窗口。 然后子窗口可以在他们的window.opener上使用postMessage 。

如果使用闪存是您的一个select,那么在安装了闪存的任何客户端( 示例代码 )上也可以实际支持更旧的LocalConnection 。

其他回退方法:
用于jQuery的postMessage插件,用于旧版浏览器的window.location.href后备
基于cookie的非即时通信解决scheme

AFAIK,如果他们不具有相同的父项,则不可能跨窗口进行通信。

如果它们都是从父窗口打开的,则应该能够获得父项的variables引用。

在父项中,像这样打开窗口:

 childA = window.open(...); childB = window.open(...) 

在ChildA中,像这样访问childB:

 childB = window.opener.childA 

我有一个很好的方法来做这样的伎俩,但有一些限制:你应该允许你的域名popup,你会得到一个页面总是打开(如选项卡或popup),将实现窗口之间的通信。

下面是一个例子: http : //test.gwpanel.org/test/page_one.html (在为域启用popup窗口后刷新页面)

这个技巧的主要特点是popup窗口最后是用“#”碎片打开,这个强制浏览器不改变窗口位置并存储所有的数据。 其余的就是window.postMessage。