SecurityError:阻止具有原点的帧访问跨源帧

时间:2014-08-02 18:14:39

标签: javascript jquery iframe same-origin-policy

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

SecurityError: Blocked a frame with origin "http://www.<domain>.com" from accessing a cross-origin frame.

您能帮我找一个解决方案,以便我可以访问框架中的元素吗?

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

$(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!";
    });
});

8 个答案:

答案 0 :(得分:649)

同源政策

不要与CORS混淆!

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

如果地址的以下部分中至少有一部分未得到维护,则认为原点不同:

<protocol>://<hostname>:<port>/path/to/page.html 
如果您要访问相框,

协议主机名端口必须与您的域相同。

实施例

以下是尝试从http://www.example.com/home/index.html

访问以下网址时会发生什么情况
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.html -> Failure: different protocol 
ftp://www.example.com:21                     -> Failure: different protocol & port 
https://google.com/search?q=james+bond       -> Failure: different hostname & protocol 

解决方法

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

  • 在您的主页中:

    message
  • var frame = document.getElementById('your-frame-id'); frame.contentWindow.postMessage(/*any variable or object here*/, '*'); (包含在主页)中:

    <iframe>

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

您的浏览器

中禁用同源策略

关于这个主题已经有了一些很好的答案(我只是发现它们谷歌搜索),因此,对于可能的浏览器,我将链接相关的答案。但是,请记住禁用同源策略(或CORS)只会影响您的浏览器。此外,运行具有相同来源安全设置的浏览器会禁止任何网站访问跨源资源,因此它非常不安全,应该仅用于开发目的

答案 1 :(得分:46)

补充Marco Bonelli的回答:帧/ iframe之间最佳的交互方式是使用window.postMessagesupported by all browsers

答案 2 :(得分:12)

检查域名的网络服务器,查看http://www.<domain>.com的{​​{1}}配置 它是一种旨在防止clickJacking攻击的安全功能,

clickJacking如何运作?

  1. 邪恶的页面看起来与受害者页面完全相同。
  2. 然后它欺骗用户输入他们的用户名和密码。
  3. 从技术上讲,邪恶的X-Frame-Options是受害者页面的来源。

    iframe

    安全功能如何工作

    如果您想阻止在<html> <iframe src='victim_domain.com'/> <input id="username" type="text" style="display: none;/> <input id="password" type="text" style="display: none;/> <script> //some JS code that click jacking the user username and input from inside the iframe... <script/> <html> 内呈现网络服务器请求,请添加x-frame-options

      

    X-Frame-Options DENY

    选项包括:

    1. SAMEORIGIN //仅允许我自己的域在iframe中呈现我的HTML。
    2. 拒绝//不允许我的HTML在任何iframe中呈现
    3. &#34;允许来自https://example.com/&#34; //允许特定域在iframe中呈现我的HTML
    4. 这是IIS配置示例:

      iframe

      问题的解决方案

      如果Web服务器激活了安全功能,它可能会导致客户端SecurityError。

答案 3 :(得分:6)

对我来说,我想实施双向握手,意思是:
  - 父窗口将加载比iframe更快的加载   - iframe一旦准备好就应该与父窗口通话   - 父母已准备好接收iframe消息并重播

此代码用于使用[CSS custom property]来设置iframe中的白色标签 代码:
IFRAME

$(function() {
    window.onload = function() {
        // create listener
        function receiveMessage(e) {
            document.documentElement.style.setProperty('--header_bg', e.data.wl.header_bg);
            document.documentElement.style.setProperty('--header_text', e.data.wl.header_text);
            document.documentElement.style.setProperty('--button_bg', e.data.wl.button_bg);
            //alert(e.data.data.header_bg);
        }
        window.addEventListener('message', receiveMessage);
        // call parent
        parent.postMessage("GetWhiteLabel","*");
    }
});

<强>父

$(function() {
    // create listener
    var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
    var eventer = window[eventMethod];
    var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
    eventer(messageEvent, function (e) {
        // replay to child (iframe) 
        document.getElementById('wrapper-iframe').contentWindow.postMessage(
            {
                event_id: 'white_label_message',
                wl: {
                    header_bg: $('#Header').css('background-color'),
                    header_text: $('#Header .HoverMenu a').css('color'),
                    button_bg: $('#Header .HoverMenu a').css('background-color')
                }
            },
            '*'
        );
    }, false);
});

自然你可以限制起源和文本,这很容易使用代码
我发现这个考试很有帮助:
[Cross-Domain Messaging With postMessage]

答案 4 :(得分:0)

我想添加特定于Java Spring的配置,以对此产生影响。

在网站或网关应用程序中,有一个contentSecurityPolicy设置

在Spring中,您可以找到WebSecurityConfigurerAdapter子类的实现

type Partial<T> = {
  [P in keyof T]?: T[P];
};
type MyUserType = Partial<firebase.User> & { myCustomProperty?: string};

...

contentSecurityPolicy("
script-src 'self' [URLDomain]/scripts ; 
style-src 'self' [URLDomain]/styles;
frame-src 'self' [URLDomain]/frameUrl...

如果您在此处未定义安全的外部域名,浏览器将被阻止。

答案 5 :(得分:0)

如果您可以控制iframe的内容-也就是说,如果它仅以跨域设置(例如在Amazon Mechanical Turk上)加载-您可以使用<body onload='my_func(my_arg)'>属性为内部html。

例如,对于内部html,使用this html参数(是-已定义this,它指向内部body元素的父窗口):

<body onload='changeForm(this)'>

在内部html中:

    function changeForm(window) {
        console.log('inner window loaded: do whatever you want with the inner html');
        window.document.getElementById('mturk_form').style.display = 'none';
    </script>

答案 6 :(得分:0)

尝试嵌入iframe,然后使用Brave打开网站时遇到了此错误。当我将相关站点更改为“ Shields Down”时,错误消失了。显然,这不是一个完整的解决方案,因为任何其他使用Brave访问该网站的人都会遇到同样的问题。要真正解决它,我需要执行此页面上列出的其他事情之一。但是至少我现在知道问题出在哪里。

答案 7 :(得分:-7)

  • 打开开始菜单
  • 键入Windows + R或打开“运行”
  • 执行以下命令。

chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security