SecurityError: Blocked a frame with origin from accessing a cross-origin frame
我在我的HTML页面中加载
1 | SecurityError: Blocked a frame with origin"http://www.<domain>.com" from accessing a cross-origin frame. |
你能帮我找一个解决方案,以便我可以访问框架中的元素吗?
我正在使用此代码进行测试,但徒劳无功:
1 2 3 4 5 6 7 8 9 10 | $(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!"; }); }); |
同源政策
不要与CORS混淆!
您无法使用JavaScript访问具有不同来源的
如果不维护地址的以下部分中的至少一个,则认为原点不同:
1 | <protocol>://<hostname>:<port>/path/to/page.html |
如果要访问框架,协议,主机名和端口必须与您的域相同。
例子
以下是尝试从
1 2 3 4 5 6 7 8 9 | 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 |
解决方法
即使同源策略阻止脚本访问具有不同来源的站点内容,如果您同时拥有这两个页面,则可以使用
-
在您的主页面中:
1
2
3let frame = document.getElementById('your-frame-id');
frame.contentWindow.postMessage(/*any variable or object here*/, '*'); -
在
中(包含在主页中): 1
2
3
4
5
6
7
8
9
10
11
12
13
14window.addEventListener('message', function(event) {
// IMPORTANT: Check the origin of the data!
if (~event.origin.indexOf('http://yoursite.com')) {
// The data has been sent from your site
// The data sent with postMessage is stored in event.data
console.log(event.data);
} else {
// The data hasn't been sent from your site!
// Be careful! Do not use it.
return;
}
});
此方法可以在两个方向上应用,也可以在主页面中创建侦听器,并从帧接收响应。同样的逻辑也可以在弹出窗口中实现,并且基本上由主页面生成的任何新窗口(例如,使用
在浏览器中禁用同源策略
关于这个主题已经有了一些很好的答案(我只是发现它们谷歌搜索),所以,对于可能的浏览器,我将链接相关的答案。但请记住,禁用同源策略(或CORS)只会影响您的浏览器。此外,运行具有相同来源安全设置的浏览器会禁止任何网站访问跨源资源,因此它非常不安全,应该仅用于开发目的。
- 谷歌浏览器
- 火狐浏览器
- Apple Safari:不可能,只有CORS。
- 歌剧:不可能。
- Microsoft Edge:不可能。
- Microsoft Internet Explorer:不可能,只有CORS。
补充Marco Bonelli的答案:帧/ iframe之间最佳的交互方式是使用
检查域的Web服务器以获取
它是一种旨在防止clickJacking攻击的安全功能,
clickJacking如何工作?
从技术上讲,邪恶有一个
1 2 3 4 5 6 7 8 | <html> <iframe src='victim_domain.com'/> <input id="username" type="text" style="display: none;/> <input id="password" type="text" style="display: none;/> //some JS code that click jacking the user username and input from inside the iframe... <script/> <html> |
安全功能如何工作
如果要阻止在
X-Frame-Options DENY
选项是:
这是IIS配置示例:
1 2 3 4 5 | <httpProtocol> <customHeaders> </customHeaders> </httpProtocol> |
问题的解决方案
如果Web服务器激活了安全功能,则可能会导致客户端SecurityError。
对我来说,我想实现双向握手,意思是:
- 父窗口加载速度比iframe快
- iframe一旦准备就应该与父窗口通话
- 父级已准备好接收iframe消息并重播
此代码用于使用[CSS自定义属性]在iframe中设置白色标签
码:
IFRAME
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | $(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","*"); } }); |
亲
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | $(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); }); |
当然,你可以限制起源和文本,这是易于使用的代码
我发现这个考试很有帮助:
[使用postMessage的跨域消息传递]
- 打开开始菜单
- 键入windows + R或打开"运行
- 执行以下命令。