背景信息:我们有一个运行在https://system.example.com
上的平台。该平台包含10个单独的Web应用程序(全部用PHP和js编写)。历史上,每个应用程序都位于同一子域内的子目录中:
https://system.example.com/app1/
https://system.example.com/app2/
https://system.example.com/app10/
我们正在重建其中一个应用程序app2
,并决定将其托管在新的单独子域https://app2.example.com
中。
app2
应用程序的一部分使用JavaScript打开app10
的弹出窗口。此弹出窗口中的大多数功能均按预期工作。但是,当尝试在弹出窗口中使用“保存”按钮时,我的浏览器控制台显示:
未捕获的DOMException:阻止了起源为“ https://app2.example.com”的框架访问跨域框架。 在https://system.example.com/app10/manage.php:1:334
我已经读过SecurityError: Blocked a frame with origin from accessing a cross-origin frame和https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage,但仍不清楚如何解决。
我拥有的代码和过程如下:
通过具有https://app2.example.com
事件处理程序的按钮从onclick
打开弹出窗口:
<button onclick="postToPopUp('https://system.example.com/app10/manage.php', 'fileManage', 'width=800px,height=600px', ['f_id', '123'], 'app2', 'filesCallbackManage')">Open app10</button>
postToPopup()
函数用于基于Javascript window.open pass values using POST将POST数据从app2
传递到https://system.example.com/app10/manage.php
-很好。
当我单击弹出窗口中的“保存”按钮时出现问题,该按钮在弹出窗口中呈现以下标记:
<!doctype HTML><html><head><title>upload</title>
<script type="text/javascript" language="javascript" charset="utf-8">
var fileObject = {"files":{"0":{"f_id":"1784","f_title":"test07.pdf"},"f_id":123}};
window.opener.filesCallbackManage(fileObject);
window.close();
</script><body></body></html>
当所有内容都在同一个子域下时,此操作最初被称为js函数filesCallbackManage()
,该函数驻留在https://system.example.com/app2
的代码中。函数本身传递了一个对象fileObject
,该对象更新了app2
中UI的各个部分。由于window.close();
尽管我已经阅读过有关使用postMessage
的信息,但我不知道它的适用范围,或者这是否是解决我的问题的正确方法?数据已从子域https://app2.example.com
正确发布到https://system.example.com/app10
。问题是filesCallbackManage()
由于跨原点限制而不会触发。在我的https://app2.example.com
代码中,有一个简单的语句可以查看是否触发:
function filesCallbackManage(data)
{
console.log('filesCallbackManage has fired');
}
由于我遇到的问题,这永远不会触发。我收到了前面提到的控制台错误和一个空白的弹出窗口(从技术上讲这是正确的,因为上面标记中的<body>
标记中没有任何内容),但是该窗口没有关闭,并且没有触发回调。 / p>
在Mozilla网站上给出的示例还不够广泛,不足以了解如何将其适应此类情况。请有人详细说明吗?此外,链接的SO帖子已经有4年历史了,所以我想确保我发布的所有信息都是安全且最新的。
任何帮助将不胜感激。
答案 0 :(得分:0)
postToPopup()函数用于传递POST数据
跨来源提交表格是可以的。因此,您可以执行此操作。
当我单击弹出窗口中的“保存”按钮时,会发生问题
您正在尝试跨源访问窗口的DOM。这是禁止的。
尽管我已经阅读过有关使用postMessage的信息,但我不了解它的适用性或这是否是解决我的问题的正确方法?
postMessage
尽可能接近跨原点访问窗口的DOM。
您不能这样做。
var fileObject = {"files":{"0":{"f_id":"1784","f_title":"test07.pdf"},"f_id":123}}; window.opener.filesCallbackManage(fileObject);
相反,您必须发送一条消息:
window.opener.postMessage(fileObject, "https://system.example.com");
并有监听它的代码:
addEventListener("message", receiveMessage);
function receiveMessage(event) {
if (event.origin !== "http://app2.example.com") { return false; }
filesCallbackManage(event.data);
}