我正在寻找一种方法,以在浏览器中的多个选项卡或窗口之间进行通信(在同一个域中,而不是在CORS上)而不会留下痕迹。有几种解决方案:
第一个可能是最糟糕的解决方案-您需要从当前窗口中打开一个窗口,然后您只能在保持窗口打开状态下进行通信。如果您在任何窗口中重新加载页面,则很可能失去了通信。
使用postMessage的第二种方法可能启用了跨域通信,但是遇到了与第一种方法相同的问题。您需要维护一个窗口对象。
第三种方法,使用cookie,将一些数据存储在浏览器中,这实际上看起来像是向同一域中的所有窗口发送消息,但是问题在于您永远无法知道所有选项卡之前是否都已经读取了“消息”打扫干净。您必须实现某种超时才能定期读取Cookie。此外,您受到最大Cookie长度(4KB)的限制。
第四个解决方案,使用localStorage,似乎克服了cookie的限制,甚至可以监听事件。已接受的答案中描述了如何使用它。
编辑2018:可接受的答案仍然有效,但是对于现代浏览器,有一个更新的解决方案可以使用BroadcastChannel。
请参阅其他答案,以获取一个简单的示例,该示例描述了如何使用BroadcastChannel轻松在选项卡之间传输消息。
如果您仍然希望使用本地存储在选项卡之间进行通信,请按照以下方式进行操作:**
为了在某个选项卡向其他选项卡发送消息时获得通知,您只需要在“存储”事件上进行绑定。在所有标签中,执行以下操作:
$(window).on('storage', message_receive);
message_receive
每次在任何其他选项卡中设置localStorage的任何值时,都会调用该函数。事件侦听器还包含新设置为localStorage的数据,因此您甚至不需要解析localStorage对象本身。这非常方便,因为您可以在设置值后立即重置该值,以有效清除任何痕迹。这是消息传递功能:
// use local storage for messaging. Set message in local storage and clear it right away
// This is a safe way how to communicate with other tabs while not leaving any traces
//
function message_broadcast(message)
{
localStorage.setItem('message',JSON.stringify(message));
localStorage.removeItem('message');
}
// receive message
//
function message_receive(ev)
{
if (ev.originalEvent.key!='message') return; // ignore other keys
var message=JSON.parse(ev.originalEvent.newValue);
if (!message) return; // ignore empty msg or msg reset
// here you act on messages.
// you can send objects like { 'command': 'doit', 'data': 'abcd' }
if (message.command == 'doit') alert(message.data);
// etc.
}
因此,现在,一旦您的选项卡绑定了onstorage事件,并且您实现了这两个功能,就可以简单地向其他选项卡调用广播消息,例如:
message_broadcast({'command':'reset'})
请记住,两次发送完全相同的消息只会传播一次,因此,如果您需要重复发送消息,请向它们添加一些唯一的标识符,例如
message_broadcast({'command':'reset', 'uid': (new Date).getTime()+Math.random()})
还请记住,广播该消息的当前选项卡实际上并没有收到,只有同一域中的其他选项卡或窗口才收到。
您可能会问,如果用户在setItem()调用之后,在removeItem()之前加载了另一个网页或关闭了他的选项卡,将会发生什么情况。好吧,根据我自己的测试,浏览器将保持卸载状态,直到整个功能message_broadcast()
完成。我测试过要放置很长的for()周期,但在关闭之前它仍然等待周期结束。如果用户只是杀死它们之间的选项卡,则浏览器将没有足够的时间将消息保存到磁盘,因此在我看来,这种方法是一种安全的方法,它可以毫无痕迹地发送消息。欢迎发表评论。
问题内容: 我正在寻找一种方法,以在浏览器中的多个选项卡或窗口之间进行通信(在同一个域中,而不是在CORS上)而不会留下痕迹。 第一个可能是最糟糕的解决方案-您需要从当前窗口中打开一个窗口,然后您只能在保持窗口打开状态下进行通信。如果您在任何窗口中重新加载页面,则很可能失去了通信。 使用postMessage的第二种方法可能启用了跨域通信,但是遇到了与第一种方法相同的问题。您需要维护一个窗口对象。
问题内容: 在同一浏览器的选项卡/窗口之间进行JavaScript通信的最可靠方法是什么?例如,当选项卡2开始播放音频时,选项卡1以某种方式知道这一点并可以暂停其播放器。 我正在建立一个带有音乐播放器的网站…因此,如果您现在打开该网站的两个标签,则可以同时在两者上播放音乐。这显然是不好的,所以我正在尝试寻找解决方案。 有任何想法吗?谢谢 问题答案: 这是一个旧的答案,我建议使用此处描述的现代版本:
我正在寻找一种方法,如何在浏览器中的多个选项卡或窗口之间进行通信(在同一个域上,而不是CORS上)而不留下痕迹。有几种解决办法: 使用窗口对象 邮件后传 Cookies 本地存储 第一种可能是最糟糕的解决方案--你需要从你当前的窗口打开一个窗口,然后你只能在保持窗口打开的情况下进行交流。如果您在任何窗口中重新加载该页,则很可能会丢失通信。 第二种方法,使用postMessage,可能可以实现跨源通
我有一个使用flink应用程序的场景,该应用程序接收以下格式的数据流: {“event\u id”:“c1s2s34”,“event\u create\u timestamp”:“2019-03-07 11:11:23”,“amount”:“104.67”} 我使用下面的滚动窗口来查找过去60秒内输入流的总和、计数和平均值。 键值。时间窗口(时间秒(60)) 然而,我如何标记聚合结果,以便我可以说
问题内容: 我有两个窗口:窗口A和窗口B。 窗口A和窗口B具有相同的域 窗口A和窗口B没有任何父窗口。 问题: 窗口A是否可以获得窗口B的引用? 使窗口A通知窗口B的最优雅方法是什么? (包括新的HTML5规范) 我知道这样做的两种方式: 服务器发送消息:窗口B经常询问服务器,窗口A是否已通知某些内容 通过本地数据(HTML5)进行消息传递:当窗口A要通知其更改本地数据的内容时,窗口B会定期检查本
问题内容: 是否可以在新标签页而不是同一标签页中打开链接? 问题答案: 您应该在锚标记中添加和。 例如: 添加不是强制性的,但这是建议的安全措施。可以在下面的链接中找到更多信息。