在不同来源的 windows 之间发送消息而不引用 window

Send messages between windows on different origins without a reference to the window

Window A是任何网站。用户在此 window 中运行一个小书签,它从我的域下载脚本。 Window B 在我的网站上并且与脚本具有相同的域。当用户运行小书签时,从 window A 向 window B 发送消息的最佳方式是什么?

我能够通过使用 window.postMessage 与我域中的隐藏 iframe 通信来实现此功能,该 iframe 使用本地存储 api 将消息转发到 window B。但是,我想知道是否有更简单的方法。

有效的方法: Window A -> postMessage -> window A -> 存储 apis -> Window B

中我域中的隐藏 iframe

有没有办法直接从 window A 转到 window B 而无需隐藏 iframe 或服务器端逻辑?

如果 windows 之间没有连接,这意味着域 A 不是域 B 的 iframe,反之亦然(并且您无法控制两者),那么您必须使用服务器端逻辑.您使用的隐藏 iframe 是一种方式,另一种方式如下:

您可以定期或有意使用 Window A 中的脚本调用站点 B,如:

var cookieScriptUrl = 'http://www.siteB.com/set_cookie.php?';
function sendData( data ) {
    var image = new Image();
    image.src = cookieScriptUrl + data;
};
sendData('likes=3');

您可以发送大量数据,请记住最大约为 2Mb。

此外,在您的 PHP 脚本中设置 cookie,您可以在 Window B.

中阅读它们

浏览器的工作就是让这种通信无法进行。如果脚本能够不受限制地在域之间传递数据,则跨站点脚本攻击的风险很高。

除了该浏览器之外,还允许通过几种方式进行此类通信:

  • postMessage 与隐藏帧对话
  • 具有所谓内容脚本的浏览器 Web 扩展可以侦听一个页面上的更改并通过 chrome.runtime.sendMessage 将它们传输到其他页面 (在 Firefox 扩展中,您可以通过多种方式进行管理)
  • 或者您可以尝试:
    • 用于在打开的选项卡之间创建通信的 WebRTC 数据通道或网络套接字
    • SharedWorkers(应充当隐藏的 iframe)

应根据您的用例使用特定技术。在某些情况下,使用后端或 cookie 可能就足够了。

为了帮助自己试验 postMessage 通信,我创建了一个名为 Spanan https://github.com/chrmod/spanan 的小库。它使用 Javascript 代理使消息传递不那么痛苦(不是实验,不是你应该在生产中使用的严肃库)