gpt4 book ai didi

javascript - 选项卡或窗口之间的通信

转载 作者:IT王子 更新时间:2023-10-29 02:37:53 26 4
gpt4 key购买 nike

我正在寻找一种方法,如何在浏览器中的多个选项卡或窗口之间进行通信(在同一域中,而不是 CORS )而不留下痕迹。有几种解决方案:

  1. using the window object
  2. postMessage
  3. cookies
  4. localStorage

第一个可能是最糟糕的解决方案 - 您需要从当前窗口打开一个窗口,然后只要保持窗口打开,您就可以进行通信。如果您在任何窗口中重新加载页面,您很可能会失去通信。

第二种方法,使用 postMessage,可能启用跨源通信,但它遇到与第一种方法相同的问题。您需要维护一个窗口对象。

第三种方式,使用 cookie,在浏览器中存储一些数据,这看起来像是向同一域中的所有窗口发送消息,但问题是您永远无法知道是否所有选项卡都读取了“消息”在清理之前已经或没有。您必须实现某种超时才能定期读取 cookie。此外,您还受到最大 Cookie 长度的限制,即 4 KB。

第四种解决方案,使用localStorage,似乎克服了cookie的限制,甚至可以使用事件监听。已接受的答案中描述了如何使用它。

在 2018 年,已接受的答案仍然有效,但现代浏览器有一个更新的解决方案,即使用 BroadcastChannel。有关描述如何使用 BroadcastChannel 在选项卡之间轻松传输消息的简单示例,请参阅其他答案。

最佳答案

您最好为此目的使用 BroadcastChannel。请参阅下面的其他答案。然而,如果您仍然更喜欢使用 localstorage 进行选项卡之间的通信,请按以下方式进行:

为了在一个选项卡向其他选项卡发送消息时得到通知,您只需绑定(bind)“存储”事件。在所有选项卡中,执行此操作:

$(window).on('storage', message_receive);

每次您在任何其他选项卡中设置 localStorage 的任何值时,都会调用函数 message_receive。事件监听器还包含新设置到 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.
}

现在,一旦您的选项卡绑定(bind)了 onstorage 事件,并且您实现了这两个功能,您就可以简单地向其他选项卡调用广播消息,例如:

message_broadcast({'command':'reset'})

请记住,发送完全相同的消息两次只会传播一次,因此如果您需要重复消息,请为它们添加一些唯一标识符,例如

message_broadcast({'command':'reset', 'uid': (new Date).getTime()+Math.random()})

还要记住,广播消息的当前选项卡实际上并没有收到它,只有同一域中的其他选项卡或窗口。

您可能会问,如果用户在 removeItem() 之前的 setItem() 调用之后加载不同的网页或关闭他的选项卡,会发生什么情况。好吧,根据我自己的测试,浏览器会暂停卸载,直到整个函数 message_broadcast() 完成。我测试了在那里放置一些很长的 for() 循环,它仍然在等待循环完成后再关闭。如果用户在中间关闭了选项卡,那么浏览器将没有足够的时间将消息保存到磁盘,因此在我看来,这种方法是一种安全的发送消息的方式,没有任何痕迹。

关于javascript - 选项卡或窗口之间的通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28230845/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com