两种选择:
document.domain
如果两个窗口都在同一个根域中并且问题是子域,您也许可以使用document.domain property 来解决它,例如在123.example.com 上的窗口中,您可以这样做:
document.domain = "example.com";
...允许它与example.com.上的窗口对话
网络消息
更通用(和现代)的解决方案是web messaging,它允许在 SOP 通常会阻止直接通信的地方进行协作跨域通信。所以我们有http://parent-origin/parent.html,它想要打开并与http://child-origin/child.html 通信。在http://parent-origin/parent.html:
// Listen for messages
window.addEventListener("message", function(e) {
// If we get a message from the child, and the message is asking for
// us to send the info...
if (e.origin === "http://child-origin" && e.data === "send-info") {
// ...send it
log("Got request from child, sending info");
e.source.postMessage({command: "info", info: { /*...data goes here...*/ }}, e.origin);
}
}, false);
在http://child-origin/child.html:
// Listen for messages
window.addEventListener("message", function(e) {
var info;
// If the message is from the parent and it says it has the info...
if (e.origin === "http://parent-origin" && e.data && e.data.command === "info") {
// Use info
info = e.data.info;
log("Info is " + JSON.stringify(info));
}
}, false);
// Ask the opener to send us the info
opener.postMessage("send-info", "http://parent-origin");
根据您打开孩子的方式(例如,如果父窗口有办法知道孩子已满载并准备好),您也许可以消除孩子向父母询问信息的部分消息)。不过,让孩子询问是确保它准备好接收信息的好方法。
最初,网络消息只允许传递字符串,但现代浏览器允许传递被克隆的对象。另请注意,如果您有canvas 对象或类似对象,您可以将它们传递到postMessage 的第三个参数中,以便它们被转移:发送者不再有权访问它们,只有接收者。这让我们可以避免复制大的东西(在可能的情况下),同时也避免了多个线程同时访问相同数据的问题。