浏览器选项卡/窗口之间的 Javascript 通信
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4079280/
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
Javascript communication between browser tabs/windows
提问by adamJLev
What's the most reliable way to have Javascript communicate between tabs/windows of the same browser? For example, when Tab 2 starts audio playback, Tab 1 somehow knows about this and can pause it's player.
让 Javascript 在同一浏览器的选项卡/窗口之间进行通信的最可靠方法是什么?例如,当 Tab 2 开始播放音频时,Tab 1 以某种方式知道这一点并且可以暂停它的播放器。
I'm building a site with a music player... so at the moment if you open two tabs to the site, you could start music on both. This is obviously bad, so I'm trying to find a solution.
我正在建立一个带有音乐播放器的网站...所以目前如果您打开该网站的两个选项卡,您可以在这两个选项卡上播放音乐。这显然很糟糕,所以我正在努力寻找解决方案。
Any ideas? Thanks
有任何想法吗?谢谢
采纳答案by Roman Goyenko
This is an old answer, I suggest to use modern version described here:
这是一个旧答案,我建议使用此处描述的现代版本:
Javascript; communication between tabs/windows with same origin
You can communicate between browser windows (and tabs too) using cookies.
您可以使用 cookie 在浏览器窗口(以及选项卡)之间进行通信。
Here is an example of sender and receiver:
以下是发送方和接收方的示例:
sender.html
发件人.html
<h1>Sender</h1>
<p>Type into the text box below and watch the text
appear automatically in the receiver.</p>
<form name="sender">
<input type="text" name="message" size="30" value="">
<input type="reset" value="Clean">
</form>
<script type="text/javascript"><!--
function setCookie(value) {
document.cookie = "cookie-msg-test=" + value + "; path=/";
return true;
}
function updateMessage() {
var t = document.forms['sender'].elements['message'];
setCookie(t.value);
setTimeout(updateMessage, 100);
}
updateMessage();
//--></script>
receiver.html:
接收器.html:
<h1>Receiver</h1>
<p>Watch the text appear in the text box below as you type it in the sender.</p>
<form name="receiver">
<input type="text" name="message" size="30" value="" readonly disabled>
</form>
<script type="text/javascript"><!--
function getCookie() {
var cname = "cookie-msg-test=";
var ca = document.cookie.split(';');
for (var i=0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(cname) == 0) {
return c.substring(cname.length, c.length);
}
}
return null;
}
function updateMessage() {
var text = getCookie();
document.forms['receiver'].elements['message'].value = text;
setTimeout(updateMessage, 100);
}
updateMessage();
//--></script>
回答by brillout
For a more modern solution check out https://stackoverflow.com/a/12514384/270274
如需更现代的解决方案,请查看https://stackoverflow.com/a/12514384/270274
Quote:
引用:
I'm sticking to the shared local data solution mentioned in the question using
localStorage
. It seems to be the best solution in terms of reliability, performance, and browser compatibility.
localStorage
is implemented in all modern browsers.The
storage
event fires when othertabs makes changes tolocalStorage
. This is quite handy for communication purposes.Reference:
http://dev.w3.org/html5/webstorage/
http://dev.w3.org/html5/webstorage/#the-storage-event
我坚持使用问题中提到的共享本地数据解决方案
localStorage
。它似乎是可靠性、性能和浏览器兼容性方面的最佳解决方案。
localStorage
在所有现代浏览器中实现。
storage
当其他选项卡对 进行更改时会触发该事件localStorage
。这对于通信目的非常方便。参考:
http: //dev.w3.org/html5/webstorage/
http://dev.w3.org/html5/webstorage/#the-storage-event
回答by donkeydown
I don't think you need cookies. Each document's js code can access the other document elements. So you can use them directly to share data. Your first window w1 opens w2 and save the reference
我认为你不需要饼干。每个文档的 js 代码都可以访问其他文档元素。因此您可以直接使用它们来共享数据。您的第一个窗口 w1 打开 w2 并保存参考
var w2 = window.open(...)
In w2 you can access w1 using the opener property of window.
在 w2 中,您可以使用 window 的 opener 属性访问 w1。
回答by Leonid Vasilev
There is also an experimental technology called Broadcast Channel API
that is designed specifically for communication between different browser contexts with same origin. You can post messages to and recieve messages from another browser context without having a reference to it:
还有一种叫做实验性的技术Broadcast Channel API
,它是专门为具有相同来源的不同浏览器上下文之间的通信而设计的。您可以向另一个浏览器上下文发布消息和从另一个浏览器上下文接收消息,而无需引用它:
var channel = new BroadcastChannel("foo");
channel.onmessage = function( e ) {
// Process messages from other contexts.
};
// Send message to other listening contexts.
channel.postMessage({ value: 42, type: "bar"});
Obviously this is experiental technology and is not supported accross all browsers yet.
显然,这是一项经验性技术,尚不支持所有浏览器。
回答by David Dehghan
You can do this via local storage API. Note that this works only between 2 tabs. you can't put both sender and receiver on the same page:
您可以通过本地存储 API 执行此操作。请注意,这仅适用于 2 个选项卡之间。您不能将发送方和接收方放在同一页面上:
On sender page:
在发件人页面上:
localStorage.setItem("someKey", "someValue");
On the receiver page
在接收页面
$(document).ready(function () {
window.addEventListener('storage', storageEventHandler, false);
function storageEventHandler(evt) {
alert("storage event called key: " + evt.key);
}
});
回答by Ashwin Aggarwal
Below window(w1) opens another window(w2). Any window can send/receive message to/from another window. So we should ideally verify that the message originated from the window(w2) we opened.
在窗口(w1)下方打开另一个窗口(w2)。任何窗口都可以向/从另一个窗口发送/接收消息。所以理想情况下,我们应该验证消息是否来自我们打开的 window(w2)。
In w1
在 w1
var w2 = window.open("abc.do");
window.addEventListener("message", function(event){
console.log(event.data);
});
In w2(abc.do)
在 w2(abc.do)
window.opener.postMessage("Hi! I'm w2", "*");
回答by Victor Stoddard
You can communicate between windows (tabbed or not) if they have a child-parent relationship.
如果窗口具有子父关系,您可以在它们之间进行通信(选项卡式或非选项卡式)。
Create and update a child window:
创建和更新子窗口:
<html>
<head>
<title>Cross window test script</title>
<script>
var i = 0;
function open_and_run() {
var w2 = window.open("", "winCounter");
var myVar=setInterval(function(){myTimer(w2)},1000);
}
function myTimer(w2) {
i++;
w2.document.body.innerHTML="<center><h1>" + i + "</h1><p></center>";
}
</script>
</head>
<body>
Click to open a new window
<button onclick="open_and_run();">Test This!</button>
</body>
</html>
Child windows can use the parent
object to communicate with the parent that spawned it, so you could control the music player from either window.
子窗口可以使用该parent
对象与生成它的父窗口进行通信,因此您可以从任一窗口控制音乐播放器。
See it in action here: https://jsbin.com/cokipotajo/edit?html,js,output
在这里查看它的实际效果:https: //jsbin.com/cokipotajo/edit?html,js,output
回答by Martin Andersson
Communicating between different JavaScript execution context was supported even before HTML5 if the documents was of the same origin. If not or you have no reference to the other Window
object, then you could use the new postMessage APIintroduced with HTML5. I elaborated a bit on both approaches in this stackoverflow answer.
如果文档来源相同,甚至在 HTML5 之前就支持在不同的 JavaScript 执行上下文之间进行通信。如果没有或者您没有对其他Window
对象的引用,那么您可以使用HTML5 引入的新postMessage API。我在这个stackoverflow answer 中详细阐述了这两种方法。
回答by jcubic
Found different way using HTML5 localstorage, I've create a library with events like API:
发现使用 HTML5 localstorage 的不同方式,我创建了一个包含 API 等事件的库:
sysend.on('foo', function(message) {
console.log(message);
});
var input = document.getElementsByTagName('input')[0];
document.getElementsByTagName('button')[0].onclick = function() {
sysend.broadcast('foo', {message: input.value});
};
it will send messages to all other pages but not for current one.
它将向所有其他页面发送消息,但不会向当前页面发送消息。
回答by Jakob Sternberg
edit: With Flash you can communicate between any window, ANY browser (yes, from FF to IE at runtime ) ..ANY form of instance of flash (ShockWave/activeX)
编辑:使用 Flash,您可以在任何窗口、任何浏览器(是的,在运行时从 FF 到 IE)之间进行通信。任何形式的 Flash 实例(ShockWave/activeX)