【问题标题】:Cross-origin security error when moving an application to a subdomain (2018)将应用程序移动到子域时出现跨域安全错误 (2018)
【发布时间】:2019-05-12 08:15:44
【问题描述】:

背景信息:我们有一个在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() 函数用于将 POST 数据从 app2 传递到基于 Javascript window.open pass values using POST 的 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');
}

由于我遇到的问题,这永远不会触发。我收到前面提到的控制台错误和一个空白的弹出窗口(从技术上讲,这是正确的,因为上述标记中的 &lt;body&gt; 标记中没有任何内容)但该窗口没有关闭并且没有触发回调。

Mozilla 网站上给出的示例不够广泛,无法理解如何适应这种情况。请问有人可以详细说明吗?此外,链接的 Stack Overflow 帖子已有四年历史,因此我想确保我在此发布的任何内容都是安全且最新的。

【问题讨论】:

    标签: javascript html security cross-domain


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2016-11-04
      • 2012-07-28
      • 1970-01-01
      • 1970-01-01
      • 2013-02-28
      • 2010-11-23
      • 2010-10-25
      • 2010-09-30
      • 1970-01-01
      相关资源
      最近更新 更多