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

#1樓

參考:https://stackoom.com/question/1hJ8n/SecurityError-阻止了具有原點的框架訪問跨域框架


#2樓

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) . 此外,運行禁用了同源安全設置的瀏覽器會授予任何網站訪問跨域資源的權限,因此這是非常不安全的,如果您不確切知道自己在做什麼(例如,出於開發目的),則永遠不要這樣做


#3樓

補充Marco Bonelli的答案:當前在框架/ iframe之間進行交互的最佳方式是使用window.postMessage所有瀏覽器均支持


#4樓

Check the domain's web server for http://www.<domain>.com configuration for X-Frame-Options It is a security feature designed to prevent clickJacking attacks, 檢查域的Web服務器以獲取X-Frame-Options http://www.<domain>.com配置。此安全功能旨在防止clickJacking攻擊,

How Does clickJacking work? clickJacking如何工作?

  1. The evil page looks exactly like the victim page. 邪惡頁面看上去與受害者頁面完全一樣。
  2. Then it tricked users to enter their username and password. 然後,它欺騙了用戶輸入用戶名和密碼。

Technically the evil has an iframe with the source to the victim page. 從技術上講,邪惡有一個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>

How the security feature work 安全功能如何工作

If you want to prevent web server request to be rendered within an iframe add the x-frame-options 如果要阻止在iframe呈現Web服務器請求,請添加x-frame-options

X-Frame-Options DENY X-Frame-Options拒絕

The options are: 選項包括:

  1. SAMEORIGIN //allow only to my own domain render my HTML inside an iframe. SAMEORIGIN //僅允許我自己的域將HTML呈現在iframe中。
  2. DENY //do not allow my HTML to be rendered inside any iframe 拒絕//不允許在任何iframe中呈現我的HTML
  3. "ALLOW-FROM https://example.com/ " //allow specific domain to render my HTML inside an iframe “ ALLOW-FROM https://example.com/ ” //允許特定域在iframe中呈現我的HTML

This is IIS config example: 這是IIS配置示例:

   <httpProtocol>
       <customHeaders>
           <add name="X-Frame-Options" value="SAMEORIGIN" />
       </customHeaders>
   </httpProtocol>

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章