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

Javascript SecurityError:阻止具有原点的帧访问跨原点帧,javascript,jquery,security,iframe,same-origin-policy,Javascript,Jquery,Security,Iframe,Same Origin Policy,我在我的HTML页面中加载了一个,并试图使用Javascript访问其中的元素,但当我尝试执行代码时,出现以下错误: SecurityError:阻止具有原点的帧http://www..com 从访问交叉原点帧。 你能帮我找到一个解决方案,这样我可以访问框架中的元素吗 我使用此代码进行测试,但徒劳: $(document).ready(function() { var iframeWindow = document.getElementById("my-iframe-id").conte

我在我的HTML页面中加载了一个,并试图使用Javascript访问其中的元素,但当我尝试执行代码时,出现以下错误:

SecurityError:阻止具有原点的帧http://www..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!";
    });
});
同一原产地政策 您不能使用JavaScript访问具有不同来源的文件,如果您可以这样做,这将是一个巨大的安全漏洞。对于浏览器,阻止脚本尝试访问具有不同原点的帧

如果地址的以下部分中至少有一部分未保留,则认为来源不同:

protocol://hostname:port/... 变通办法 即使同源策略阻止脚本访问具有不同来源的站点的内容,但如果您拥有这两个页面,您可以使用及其相关消息事件在这两个页面之间发送消息来解决此问题,如下所示:

在主页中:

const frame = document.getElementById('your-frame-id');
frame.contentWindow.postMessage(/*any variable or object here*/, 'http://your-second-site.com');
window.addEventListener('message', event => {
    // IMPORTANT: check the origin of the data! 
    if (event.origin.startsWith('http://your-first-site.com')) { 
        // 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; 
    } 
}); 
postMessage的第二个参数可以是“*”以表示对目标的来源没有偏好。在可能的情况下,应始终提供目标来源,以避免泄露您发送到任何其他站点的数据

在主页中包含的内容中:

const frame = document.getElementById('your-frame-id');
frame.contentWindow.postMessage(/*any variable or object here*/, 'http://your-second-site.com');
window.addEventListener('message', event => {
    // IMPORTANT: check the origin of the data! 
    if (event.origin.startsWith('http://your-first-site.com')) { 
        // 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; 
    } 
}); 
此方法可以在两个方向上应用,在主页中也创建一个侦听器,并从框架接收响应。同样的逻辑也可以在弹出窗口和主页生成的任何新窗口中实现,例如使用,没有任何区别

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

Microsoft Edge:
补充Marco Bonelli的回答:当前帧/iFrame之间交互的最佳方式是使用,

检查域的web服务器以了解http://www..com 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>
问题的解决办法
如果web服务器激活了安全功能,可能会导致客户端安全错误。

对我来说,我想实现双向握手,意思是: -父窗口的加载速度将快于iframe -iframe应在准备就绪后立即与父窗口对话 -父级已准备好接收iframe消息并重播

此代码用于使用设置iframe中的白色标签 代码: iframe

母公司

当然,您可以限制源代码和文本,这很容易使用代码 我发现这个例子很有帮助:

打开“开始”菜单 键入windows+R或open Run 执行以下命令。
chrome.exe-user data dir=C://chrome dev session-disable web security

我想添加Java Spring特定的配置,可以对其产生影响

在网站或网关应用程序中,存在contentSecurityPolicy设置

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

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


如果您没有在此处定义安全的外部contenet,浏览器将被阻止。

如果您可以控制iframe的内容,也就是说,如果它仅在跨源设置(如Amazon Mechanical Turk)中加载,则可以使用内部html的属性来避免此问题

例如,对于内部html,使用this html参数yes-这是已定义的,它引用内部主体元素的父窗口:

在内部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>

我在尝试嵌入iframe,然后用Brave打开站点时遇到了这个错误。当我为讨论中的站点切换到Shields Down时,错误消失了。显然,这并不是一个完整的解决方案,因为任何其他带着Brave访问网站的人都会遇到同样的问题。要真正解决这个问题,我需要做本页列出的其他事情之一。但至少我现在知道了问题所在。

我找到的任何其他答案都表明CORS/Access Control Allow Origin不适用于iFrame,只适用于iFrame。我相信postMessage是唯一的选项。@ccppjava您不需要===,您已经知道变量类型是字符串,所以===在这里是无用的。@SABAHANG只需检查iframe.src,如果
如果它与域的主机名不同,则无法访问该帧。@user2568374这是个糟糕的主意。如果检查event.origin.indexOflocation.ancestorOrigins[0],基本上就是允许任何父帧访问您的帧,正如您所想象的,这是一个非常糟糕的主意。@user2568374 location.ancestorOrigins[0]是父帧的位置。如果您的帧在另一个站点内运行,并且您使用event.origin.indexOflocation.ancestorOrigins[0]进行检查,则您正在检查事件的源是否包含父帧地址(该地址始终为真),因此您允许具有任何源的任何父帧访问您的帧,这显然不是你想做的事情。此外,document.referer也是一种不好的做法,正如我在上面的评论中所解释的那样。window.postMessage只有在能够访问parentour HTML页面和children element其他域iframe时,我们才能使用。否则,就不可能,它总是会抛出一个错误Uncaught DomeException:阻止源代码为的帧访问跨源代码帧。我正在处理safari的一个问题,其中iframe中的文档执行其JS的时间晚于父页面,这导致消息发送的时间早于iframe中的文档侦听消息的时间;这与chrome和firefox的做法完全相反——你在ios上的safari中测试过你的代码吗?顺便说一句,第二个参数值为*的postMessage不太安全,您应该始终指定Domain您的第一个代码块,是在父级的iframe上还是在加载到iframe的页面上?对于任何不是快速且肮脏的测试…并且已经在接受的答案中找到地址的代码块来说都很糟糕。即使使用命令,这不起作用,因为Chrome避免了以这种方式禁用web安全性。我不认为X-Frame-Options适用于此-来宾嵌入页面定义的X-Frame-Options可能会导致家长拒绝加载页面,但据我所知,它不会影响javascript访问-即使使用X-Frame-Options:*,我认为您无法使用javascript访问不同来源的来宾页面的DOM
.referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
    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>