我正在寻找一种方法,如何在浏览器中的多个选项卡或窗口(在同一域上,而不是CORS)之间进行通信而不留下痕迹。有几种解决方案:
使用window对象
postMessage
饼干
localStorage
第一种可能是最糟糕的解决方案——您需要从当前窗口打开一个窗口,然后您只能在保持窗口打开的情况下进行通信。如果在任何窗口中重新加载页面,很可能会失去通信。
第二种方法(使用postMessage)可能支持跨源通信,但它遇到了与第一种方法相同的问题。您需要维护一个窗口对象。
第三种方法是使用cookie,在浏览器中存储一些数据,这实际上看起来像是向同一域上的所有窗口发送消息,但问题是,在清理之前,您永远无法知道所有选项卡是否已经阅读了“消息”。您必须实现某种类型的超时来定期读取cookie。此外,您还受到最大cookie长度(4 KB)的限制。
第四种解决方案,使用localStorage,似乎克服了cookie的限制,甚至可以使用事件监听。如何使用它在公认的答案中有描述。
我创建了一个syend .js库,用于在浏览器选项卡和窗口之间发送消息。该库没有任何外部依赖项。
您可以使用它在同一浏览器和域中的选项卡/窗口之间进行通信。该库使用BroadcastChannel(如果支持)或localStorage中的存储事件。
API非常简单:
sysend.on('foo', function(data) {
console.log(data);
});
sysend.broadcast('foo', {message: 'Hello'});
sysend.broadcast('foo', "hello");
sysend.broadcast('foo', ["hello", "world"]);
sysend.broadcast('foo'); // empty notification
当您的浏览器支持BroadcastChannel时,它会发送一个文本对象(但实际上是由浏览器自动序列化的),如果不支持,则先将其序列化为JSON,然后在另一端反序列化。
最新版本还提供了一个帮助API,用于创建跨域通信的代理(它需要目标域上的单个HTML文件)。
这里是一个演示。
新版本也支持跨域通信,如果你在目标域中包含一个特殊的proxy.html文件,并从源域中调用代理函数:
sysend.proxy('https://target.com');
(proxy.html是一个非常简单的HTML文件,它只有一个带有库的脚本标记)。
如果你想要双向通信,你需要在其他域上做同样的事情。
注意:如果您将使用localStorage实现相同的功能,则Internet Explorer中存在一个问题。存储事件被发送到相同的窗口,这触发了事件,对于其他浏览器,它只被其他选项卡/窗口调用。
我在我的博客上写过一篇文章:跨浏览器选项卡共享sessionStorage数据。
使用一个库,我创建了storageManager。你可以通过以下方法实现:
storageManager.savePermanentData('data', 'key'): //saves permanent data
storageManager.saveSyncedSessionData('data', 'key'); //saves session data to all opened tabs
storageManager.saveSessionData('data', 'key'); //saves session data to current tab only
storageManager.getData('key'); //retrieves data
还有其他方便的方法来处理其他场景。
我创建了一个syend .js库,用于在浏览器选项卡和窗口之间发送消息。该库没有任何外部依赖项。
您可以使用它在同一浏览器和域中的选项卡/窗口之间进行通信。该库使用BroadcastChannel(如果支持)或localStorage中的存储事件。
API非常简单:
sysend.on('foo', function(data) {
console.log(data);
});
sysend.broadcast('foo', {message: 'Hello'});
sysend.broadcast('foo', "hello");
sysend.broadcast('foo', ["hello", "world"]);
sysend.broadcast('foo'); // empty notification
当您的浏览器支持BroadcastChannel时,它会发送一个文本对象(但实际上是由浏览器自动序列化的),如果不支持,则先将其序列化为JSON,然后在另一端反序列化。
最新版本还提供了一个帮助API,用于创建跨域通信的代理(它需要目标域上的单个HTML文件)。
这里是一个演示。
新版本也支持跨域通信,如果你在目标域中包含一个特殊的proxy.html文件,并从源域中调用代理函数:
sysend.proxy('https://target.com');
(proxy.html是一个非常简单的HTML文件,它只有一个带有库的脚本标记)。
如果你想要双向通信,你需要在其他域上做同样的事情。
注意:如果您将使用localStorage实现相同的功能,则Internet Explorer中存在一个问题。存储事件被发送到相同的窗口,这触发了事件,对于其他浏览器,它只被其他选项卡/窗口调用。
Checkout acrosstab -跨源浏览器选项卡之间的轻松通信。它使用postMessage和sessionStorage api的组合,使通信更加容易和可靠。
有不同的方法,每一个都有自己的优点和缺点。让我们分别讨论一下:
LocalStorage
Pros:
Web storage can be viewed simplistically as an improvement on cookies, providing much greater storage capacity. If you look at the Mozilla source code we can see that 5120 KB (5 MB which equals 2.5 million characters on Chrome) is the default storage size for an entire domain. This gives you considerably more space to work with than a typical 4 KB cookie.
The data is not sent back to the server for every HTTP request (HTML, images, JavaScript, CSS, etc.) - reducing the amount of traffic between client and server.
The data stored in localStorage persists until explicitly deleted. Changes made are saved and available for all current and future visits to the site.
Cons:
It works on same-origin policy. So, data stored will only be able available on the same origin.
Cookies
Pros:
Compared to others, there's nothing AFAIK.
Cons:
The 4 KB limit is for the entire cookie, including name, value, expiry date, etc. To support most browsers, keep the name under 4000 bytes, and the overall cookie size under 4093 bytes.
The data is sent back to the server for every HTTP request (HTML, images, JavaScript, CSS, etc.) - increasing the amount of traffic between client and server.
Typically, the following are allowed:
300 cookies in total
4096 bytes per cookie
20 cookies per domain
81920 bytes per domain (given 20 cookies of the maximum size 4096 = 81920 bytes.)
sessionStorage
Pros:
It is similar to localStorage.
Changes are only available per window (or tab in browsers like Chrome and Firefox). Changes made are saved and available for the current page, as well as future visits to the site on the same window. Once the window is closed, the storage is deleted
Cons:
The data is available only inside the window/tab in which it was set.
The data is not persistent, i.e., it will be lost once the window/tab is closed.
Like localStorage, tt works on same-origin policy. So, data stored will only be able available on the same origin.
PostMessage
Pros:
Safely enables cross-origin communication.
As a data point, the WebKit implementation (used by Safari and Chrome) doesn't currently enforce any limits (other than those imposed by running out of memory).
Cons:
Need to open a window from the current window and then can communicate only as long as you keep the windows open.
Security concerns - Sending strings via postMessage is that you will pick up other postMessage events published by other JavaScript plugins, so be sure to implement a targetOrigin and a sanity check for the data being passed on to the messages listener.
A combination of PostMessage + SessionStorage
Using postMessage to communicate between multiple tabs and at the same time using sessionStorage in all the newly opened tabs/windows to persist data being passed. Data will be persisted as long as the tabs/windows remain opened. So, even if the opener tab/window gets closed, the opened tabs/windows will have the entire data even after getting refreshed.
我为此写了一个JavaScript库,名为acrosstab,它使用postMessage API在跨源选项卡/窗口和sessionStorage之间进行通信,以持久化打开的选项卡/窗口标识,只要它们存在。