Javascript window.opener.postMessage具有多个子域的跨源

时间:2018-08-24 10:33:16

标签: javascript cross-domain postmessage multiple-domains

我正在尝试允许多个子域:

window.opener.postMessage(...);

这可行,但这并不安全,因为所有可能的域都被允许,我不希望这样做:

window.opener.postMessage('MyMSG', '*');

这适用于单个域:

window.opener.postMessage('MyMSG', 'https://example.com');

但是,如果我想允许这样做:* .example.com吗?

当然是这样:

window.opener.postMessage('MyMSG', '*.example.com');
window.opener.postMessage('MyMSG', 'https://*.example.com');
window.opener.postMessage('MyMSG', 'https://(.*)example.com');

不起作用

正确的做法是什么?那有可能吗?

谢谢

1 个答案:

答案 0 :(得分:4)

targetOrigin期望*或确切的uri,即没有子域通配符。

如果要发布到多个目标,则每个目标都需要单独的postMessage()调用。为了简化操作,您可以将所有域放入列表中并在列表上进行迭代,而不是对每个调用进行硬编码。

var someData = {};
var subdomains = ["one","two","three"];
for(var subdomain of subdomains){
  let target = "http://"+subdomain+".example.com"
  window.postMessage(someData,target);
}

但这会带来保持列表更新的维护成本

现在,根据您的代码在哪一端,您还可以使用某些方法在运行时获取确切的uri。注意示例使用URL来仅解析协议和主机,以获取适当的值以传递给postMessage。

如果您是打开窗口的一端,或者是iframe的父窗口,则只需获取src,href或用于指示窗口,iframe等网址的任何属性即可。

//if using for instance window.open()
//you already know the url as it has to be passed to the function
var target = window.open("http://example.com/some/path");

//so in this case you would first save the url to a variable and use that variable for both
var url = new URL("http://example.com/some/path");
var targetDomain = url.protocol + "//" + url.host;

var target = window.open(url.href);
target.postMessage("message",targetDomain);

//if using an iframe just grab the src property and parse the domain from that
var url = new URL(iframeElement.src);
var targetDomain = url.protocol+"//"+url.host;
iframeElement.contentWindow.postMessage("message",targetDomain);

现在,如果您在另一侧,即在iframe或打开的窗口中,则可以使用document.referrer,但从安全页面打开非安全网址时除外。这意味着在页面使用document.referrer

时打开http://网址时不会设置https://
var url = new URL( document.referrer );
var target = url.protocol+"//"+url.host;
//opened window
window.opener.postMessage("message",target);
//iframe
window.parent.postMessage("message",target);