js-将应用程序移至子域时发生跨域安全错误(2018)

时间:2018-12-11 10:47:59

标签: javascript html security cross-domain

背景信息:我们有一个运行在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 framehttps://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年历史了,所以我想确保我发布的所有信息都是安全且最新的。

任何帮助将不胜感激。

1 个答案:

答案 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);
}