use*_*298 3 javascript cross-domain
我有一个像123.example.com这样的子域名网址,因为我正在使用谷歌或Facebook进行Oauth登录.现在的程序就像当我点击google或facebook登录时,会弹出一个窗口,然后会出现详细信息,在获取详细信息后,我想在父窗口中显示详细信息.所以我正在使用window.opener.$("#first_name").val(firstName);,我收到这样的错误错误:拒绝访问属性'$'的权限.如果它不是子域,它的工作正常.如何将值获取到主窗口.
有两种选择:
document.domain如果两个窗口都位于同一个根域,并且问题是子域,则可以使用该document.domain属性解决它,例如在a上的窗口中123.example.com,您可以执行以下操作:
document.domain = "example.com";
Run Code Online (Sandbox Code Playgroud)
...允许它与Windows通话 example.com.
更一般(和现代)的解决方案是Web消息传递,它允许在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);
Run Code Online (Sandbox Code Playgroud)
在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");
Run Code Online (Sandbox Code Playgroud)
您可以根据您打开孩子的方式消除孩子要求父母提供信息的部分(例如,如果父窗口有一种方法可以知道孩子已经满载并准备好了消息).然而,让孩子询问是一种非常好的方法,可以确保它已准备好接收信息.
最初,Web消息传递只允许传递字符串,但现代浏览器允许传递被克隆的对象.另请注意,如果您有canvas对象或类似对象,您可以在第三个参数中传递它们,postMessage以便它们被传输:发送方不再能够访问它们,只有接收方.这使我们可以避免复制大的东西(如果可能),同时避免多个线程同时访问相同数据的问题.