Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
503 views
in Technique[技术] by (71.8m points)

javascript - SecurityError:阻止了具有原点的框架访问跨域框架(SecurityError: Blocked a frame with origin from accessing a cross-origin frame)

I am loading an <iframe> 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页面中加载<iframe>并尝试使用Javascript访问其中的元素,但是当我尝试执行代码时,出现以下错误:)

SecurityError: Blocked a frame with origin "http://www.<domain>.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!";
    });
});
  ask by mubashermubi translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Same-origin policy(同源政策)

You can't access an <iframe> with different origin using JavaScript, it would be a huge security flaw if you could do it.

(您无法使用JavaScript访问具有不同来源的<iframe> ,如果可以的话,这将是一个巨大的安全漏洞。)

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:

(如果未保留地址的以下至少其中之一,则认为起源是不同的:)

<protocol>://<hostname>:<port>/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并不严格遵循此规则,有关详细信息,请参见此处)

Examples(例子)

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 

Workaround(解决方法)

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 <iframe> (contained in the main page):

    (在您的<iframe> (包含在主页中):)

     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() ),而没有任何区别。)

Disabling same-origin policy in your browser(在您的浏览器禁用同源策略)

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) .

(此外,运行禁用了同源安全设置的浏览器会授予任何网站访问跨域资源的权限,因此这是非常不安全的,如果您不确切知道自己在做什么(例如,出于开发目的),则永远不要这样做 。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...