本文翻译自:SecurityError: Blocked a frame with origin from accessing a cross-origin frame
I am loading an in my HTML page and trying to access the elements within it using Javascript, but when I try to execute my code, I get the following error: 我在HTML页面中加载
并尝试使用Javascript访问其中的元素,但是当我尝试执行代码时,出现以下错误:
SecurityError: Blocked a frame with origin "http://www..com" from accessing a cross-origin frame.
Can you please help me to find a solution so that I can access the elements in the frame? 您能否帮助我找到解决方案,以便我可以访问框架中的元素?
I am using this code for testing, but in vain: 我正在使用此代码进行测试,但徒劳无功:
$(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!";
});
});
参考:https://stackoom.com/question/1hJ8n/SecurityError-阻止了具有原点的框架访问跨域框架
You can't access an with different origin using JavaScript, it would be a huge security flaw if you could do it. 您无法使用JavaScript访问具有不同来源的
,如果可以的话,这将是一个巨大的安全漏洞。 For the same-origin policy browsers block scripts trying to access a frame with a different origin . 对于同源策略, 浏览器会阻止脚本尝试访问来源不同的框架 。
Origin is considered different if at least one of the following parts of the address isn't maintained: 如果未保留地址的以下至少其中之一,则认为起源是不同的:
://:/path/to/page.html
Protocol , hostname and port must be the same of your domain, if you want to access a frame. 如果要访问框架, 协议 , 主机名和端口必须与您的域相同。
NOTE: Internet Explorer is known to not strictly follow this rule, see here for details. 注意:众所周知,Internet Explorer并不严格遵循此规则,有关详细信息,请参见此处 。
Here's what would happen trying to access the following URLs from http://www.example.com/home/index.html
尝试从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
Even though same-origin policy blocks scripts from accessing the content of sites with a different origin, if you own both the pages, you can work around this problem using window.postMessage
and its relative message
event to send messages between the two pages, like this: 即使同源策略阻止脚本访问来源不同的站点的内容,但是如果您同时拥有两个页面,则可以使用window.postMessage
及其相对message
事件在两个页面之间发送消息,从而解决此问题。这个:
In your main page: 在您的主页中:
let frame = document.getElementById('your-frame-id'); frame.contentWindow.postMessage(/*any variable or object here*/, 'http://your-second-site.com');
The second argument to postMessage()
can be '*'
to indicate no preference about the origin of the destination. postMessage()
的第二个参数可以为'*'
以表示对目标来源没有任何偏好。 A target origin should always be provided when possible, to avoid disclosing the data you send to any other site. 在可能的情况下,应始终提供目标来源,以避免泄露您发送到任何其他站点的数据。
In your (contained in the main page): 在您的
(包含在主页中):
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; } });
This method can be applied in both directions , creating a listener in the main page too, and receiving responses from the frame. 此方法可以在两个方向上应用,也可以在主页上创建侦听器,并从框架接收响应。 The same logic can also be implemented in pop-ups and basically any new window generated by the main page (eg using window.open()
) as well, without any difference. 相同的逻辑也可以在弹出窗口中实现,并且基本上也可以在主页中生成的任何新窗口中实现(例如,使用window.open()
),而没有任何区别。
There already are some good answers about this topic (I just found them googling), so, for the browsers where this is possible, I'll link the relative answer. 关于这个主题已经有了一些很好的答案(我刚刚找到了它们),因此,对于可能的浏览器,我将链接相对答案。 However, please remember that disabling the same-origin policy will only affect your browser . 但是,请记住, 禁用同源策略只会影响您的浏览器 。 Also, running a browser with same-origin security settings disabled grants any website access to cross-origin resources, so it's very unsafe and should NEVER be done if you do not know exactly what you are doing (eg development purposes) . 此外,运行禁用了同源安全设置的浏览器会授予任何网站访问跨域资源的权限,因此这是非常不安全的,如果您不确切知道自己在做什么(例如,出于开发目的),则永远不要这样做 。
补充Marco Bonelli的答案:当前在框架/ iframe之间进行交互的最佳方式是使用window.postMessage
, 所有浏览器均支持
Check the domain's web server for http://www.
configuration for X-Frame-Options
It is a security feature designed to prevent clickJacking attacks, 检查域的Web服务器以获取X-Frame-Options
http://www.
配置。此安全功能旨在防止clickJacking攻击,
Technically the evil has an iframe
with the source to the victim page. 从技术上讲,邪恶有一个iframe
,其中包含受害者页面的源代码。
“ ALLOW-FROM https://example.com/ ” //允许特定域在iframe中呈现我的HTML
This is IIS config example: 这是IIS配置示例:
The solution to the question 问题的解决方案
If the web server activated the security feature it may cause a client-side SecurityError as it should. 如果Web服务器激活了安全功能,则可能会导致客户端安全错误。
#5楼
For me i wanted to implement a 2-way handshake, meaning: 对我来说,我想实现两路握手,这意味着:
- the parent window will load faster then the iframe -父窗口的加载速度比iframe快
- the iframe should talk to the parent window as soon as its ready -iframe准备就绪后应立即与父窗口进行对话
- the parent is ready to receive the iframe message and replay -家长已准备好接收iframe消息并进行重播
this code is used to set white label in the iframe using [CSS custom property] 此代码用于使用[CSS自定义属性]在iframe中设置白色标签
code: 码:
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","*");
}
});
parent 父母
$(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);
});
naturally you can limit the origins and the text, this is easy-to-work-with code 自然地,您可以限制原点和文本,这是易于使用的代码
i found this examlpe to be helpful: 我发现此示例很有帮助:
[Cross-Domain Messaging With postMessage] [使用postMessage进行跨域消息传递]
#6楼
- Open the start menu 打开开始菜单
- Type windows+R or open "Run 键入Windows + R或打开“运行
- Execute the following command. 执行以下命令。
chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security