Javascript;具有相同原点的选项卡/窗口之间的通信

Javascript;具有相同原点的选项卡/窗口之间的通信,javascript,html,web-applications,local-storage,postmessage,Javascript,Html,Web Applications,Local Storage,Postmessage,我有两扇窗户:A窗和B窗 窗口A和窗口B具有相同的域 窗口A和窗口B没有任何父窗口 问题: 窗口A是否可以获得窗口B的参考 让窗口A通知窗口B的最优雅方式是什么? (包括新的HTML5规范) 我知道这样做有两种方式: 按服务器发送消息:窗口B定期询问服务器窗口A是否已通知某些内容 本地数据消息传递(HTML5):当窗口A想要通知它更改本地数据的内容时,窗口B会定期检查本地数据是否有任何更改 但这两种方式并不那么优雅。 例如,获取window B的引用并使用window.postMessa

我有两扇窗户:A窗和B窗

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

  • 窗口A是否可以获得窗口B的参考
  • 让窗口A通知窗口B的最优雅方式是什么?
    (包括新的HTML5规范)
  • 我知道这样做有两种方式:

    • 按服务器发送消息:窗口B定期询问服务器窗口A是否已通知某些内容
    • 本地数据消息传递(HTML5):当窗口A想要通知它更改本地数据的内容时,窗口B会定期检查本地数据是否有任何更改
    但这两种方式并不那么优雅。
    例如,获取window B的引用并使用window.postMessage()(HTML5)会很好


    最终目标是制作类似facebook的东西,如果你打开4个facebook标签,在一个标签上聊天,那么每个facebook标签上的聊天都是最新的,这很好

    好吧,如果没有相同的父窗口,那么就不可能跨窗口通信

    如果它们都是从父窗口打开的,您应该能够获得父窗口的变量引用

    在父级中,按如下方式打开窗口:

    childA = window.open(...);
    childB = window.open(...)
    
    childB = window.opener.childA
    
    在ChildA中,按如下方式访问childB:

    childA = window.open(...);
    childB = window.open(...)
    
    childB = window.opener.childA
    
    你说你的:

    Utilimate的目标是制作类似facebook的东西,如果你打开4个facebook标签,在一个标签上聊天,那么每个facebook标签上的聊天都会实现,这很好

    这应该是您设计的副产品,视图查询模型(可能是服务器)以更新聊天,而不是您必须在交叉视图通信中进行设计。除非你处理的是大量的数据传输,为什么还要担心呢?这似乎会使事情复杂化,而不会带来巨大的收益


    几年前,我发现如果我使用一个现有窗口的名称和一个空白URL打开
    window.open,我会得到一个对现有窗口的引用(这种行为是公平的,一条评论表明它也适用于IE;也就是说,2017年,有人在MDN文章中添加了一些限制——我还没有独立验证它们).但那是几年前的事了,我不知道当今世界对它的支持有多普遍,当然,除非所有窗口都包含一个用于通信的命名的
    iframe
    ,通过服务器端代码进行唯一命名,然后通过服务器端代码与其他窗口通信,否则您将无法找到窗口名。。。(可怕的想法:这实际上可能是可行的。储存“电流”与表中登录帐户相关的窗口名称,将列表提供给登录该帐户的任何新窗口,剔除旧的非活动条目。但是,如果列表稍微过时,您将在搜索其他窗口时打开新窗口…我打赌不同浏览器之间的支持是不确定的。)

    我有一个巧妙的方法来实现这样的技巧,但有一些限制:你应该允许你的域中出现弹出窗口,你会得到一个始终打开的页面(作为选项卡或弹出窗口),这将实现窗口之间的通信

    下面是一个例子: (为域启用弹出窗口后刷新页面)

    这个技巧的主要特点是弹出窗口是用url片段“#”打开的。最后,这迫使浏览器不改变窗口位置并存储所有数据。
    其余部分由window.postMessage完成。

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

    除了即将发布的,您还可以使用,它的应用范围更广。在这种情况下,必须有一个主窗口负责使用
    窗口打开所有其他窗口。打开
    然后,ild窗口可以在其
    窗口上使用

    如果您可以选择使用flash,那么任何安装了flash()的客户端都会支持更旧的版本

    其他回退方法:


    我坚持问题中提到的使用
    localStorage
    的共享本地数据解决方案。从可靠性、性能和浏览器兼容性来看,它似乎是最好的解决方案

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

    当其他选项卡对
    localStorage
    进行更改时,
    storage
    事件将触发。这对于通信目的非常方便

    可在此处找到参考资料:


    广播频道标准允许这样做。现在它在Firefox和Chrome(,)中实现:


    问题仍然存在:让他们交流的最优雅的方式是什么?即使是间接的,例如通过服务器。事实上,facebook做到了这一点,这是可能的。谢谢你的代表!@romuwild:欢迎你的代表;-)看起来这是你唯一的选择(通过服务器)。您可能有兴趣知道facebook使用长轮询comet,这是一种http交互,服务器不会终止连接,而是在连接可用时通过连接推送数据。请参阅。或者通过本地数据而不是服务器。但是,yeah似乎是唯一的选项。感谢链接,我没有意识到!真的这就是我基本上正在做的:web应用程序的整个状态都存储在浏览器的本地数据中。由于本地数据由窗口A和B共享,如果窗口A更改本地数据,窗口B只需重新读取本地数据即可获得新状态。但对于它,窗口B需要知道何时必须重新读取本地数据。一种方法是让window B定期检查本地数据。但是让window A告诉window B“嘿,window B,检查新的状态并重新读取本地数据”会更好!这是一个很好的窗口引用技巧。我刚刚尝试了你的技巧与window.postMessage()相结合,即window.open(null,'windo