SecurityError:阻止具有源的框架访问跨域框架

新手上路,请多包涵

我在我的 HTML 页面中加载 <iframe> 并尝试使用 JavaScript 访问其中的元素,但是当我尝试执行我的代码时,我收到以下错误:

SecurityError: 阻止了来源为“ http://www.example.com”的框架访问跨域框架。

如何访问框架中的元素?

我正在使用此代码进行测试,但徒劳无功:

$(document).ready(function() {
    var iframeWindow = document.getElementById("my-iframe-id").contentWindow;

    iframeWindow.addEventListener("load", function() {
        var doc = iframe.contentDocument || iframe.contentWindow.document;
        var target = doc.getElementById("my-target-id");

        target.innerHTML = "Found it!";
    });
});

原文由 mubashermubi 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

同源政策

无法 使用 JavaScript 访问具有不同来源的 <iframe> ,如果您可以这样做,那将是一个巨大的安全漏洞。对于 同源策略 ,浏览器会阻止脚本尝试访问具有不同源的框架

如果未维护地址的以下部分中的至少一个,则认为来源不同:

协议://主机名:端口/...

如果您想访问一个框架,协议、主机名和端口必须与您的域相同。

注意:众所周知,Internet Explorer 并不严格遵循此规则,请参阅 此处 了解详细信息。

例子

以下是尝试从 http://www.example.com/home/index.html 访问以下 URL 时会发生的情况

URL RESULT
 http://www.example.com/home/other.html -> Success
 http://www.example.com/dir/inner/another.php -> Success
 http://www.example.com:80 -> Success (default port for HTTP)
 http://www.example.com:2251 -> Failure: different port
 http://data.example.com/dir/other.html -> Failure: different hostname
 https://www.example.com/home/index.html:80 -> Failure: different protocol
 ftp://www.example.com:21 -> Failure: different protocol & port
 https://google.com/search?q=james+bond -> Failure: different protocol, port & hostname

解决方法

即使同源策略阻止脚本访问具有不同来源的站点的内容, 如果您拥有这两个页面,您可以使用 window.postMessage 及其相关 message 事件在两个页面之间发送消息来解决此问题,例如这个:

  • 在您的主页中:
 const frame = document.getElementById('your-frame-id');
 frame.contentWindow.postMessage(/*any variable or object here*/, 'http://your-second-site.example');

postMessage() 的第二个参数可以是 '*' 以表示对目的地的来源没有偏好。应尽可能提供目标来源,以避免泄露您发送到任何其他站点的数据。

  • 在您的 <iframe> 中(包含在主页中):
 window.addEventListener('message', event => {
 // IMPORTANT: check the origin of the data!
 if (event.origin.startsWith('http://your-first-site.example')) {
 // The data was sent from your site.
 // Data sent with postMessage is stored in event.data:
 console.log(event.data);
 } else {
 // The data was NOT sent from your site!
 // Be careful! Do not use it. This else branch is
 // here just for clarity, you usually shouldn't need it.
 return;
 }
 });

该方法可以 双向 应用,也可以在主页中创建监听器,并接收框架的响应。同样的逻辑也可以在弹出窗口和基本上由主页生成的任何新窗口(例如使用 window.open() )中实现,没有任何区别。

浏览 器中禁用同源策略

关于这个主题已经有一些很好的答案(我刚刚发现他们在谷歌上搜索),因此,对于可能的浏览器,我将链接相关答案。但是请记住, 禁用同源策略只会影响 您的 浏览器。此外,在禁用同源安全设置的情况下运行浏览器会授予 任何 网站对跨源资源的访问权限,因此 这是非常不安全的,如果您不确切知道自己在做什么(例如开发目的),则永远不要这样做

原文由 Marco Bonelli 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题