it-swarm.com.ru

SecurityError: заблокирован кадр с источником из-за доступа к кросс-исходному кадру

Я загружаю <iframe> в мою HTML-страницу и пытаюсь получить доступ к элементам внутри нее, используя Javascript, но когда я пытаюсь выполнить свой код, я получаю следующую ошибку:

SecurityError: Blocked a frame with Origin "http://www.<domain>.com" from accessing a cross-Origin frame.

Не могли бы вы помочь мне найти решение, чтобы я мог получить доступ к элементам в рамке?

Я использую этот код для тестирования, но напрасно:

$(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!";
    });
});
427
mubashermubi

Политика одного происхождения

Не путать с CORS !

Вы не можете получить доступ к <iframe> с другим источником, используя JavaScript, это было бы огромным недостатком безопасности, если бы вы могли это сделать. Для браузеров политика того же источника блокируют сценарии, пытаясь получить доступ к кадру с другим источником .

Источник считается другим, если не поддерживается хотя бы одна из следующих частей адреса:

<protocol>://<hostname>:<port>/path/to/page.html 

Протокол , имя хоста и порт должен совпадать с вашим доменом, если вы хотите получить доступ к фрейму.

Примеры

Вот что произойдет при попытке получить доступ к следующим URL-адресам из http://www.example.com/home/index.html

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 

Workaround

Несмотря на то, что политика одного и того же источника блокирует доступ сценариев к содержимому сайтов с другим источником, если вы владеете обеими страницами, вы можете обойти эту проблему, используя window.postMessage и относительное событие message для отправки сообщений между двумя страницами, например так:

  • На вашей главной странице:

    var frame = document.getElementById('your-frame-id'); 
    
    frame.contentWindow.postMessage(/*any variable or object here*/, '*'); 
    
  • В вашем <iframe> (содержится на главной странице):

    window.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; 
        } 
    }); 
    

Этот метод может применяться в обоих направлениях , создавая слушателя на главной странице и получая ответы из фрейма. Та же логика также может быть реализована во всплывающих окнах и в основном в любом новом окне, сгенерированном главной страницей (например, с использованием window.open() ), без каких-либо различий.

Отключение политики того же происхождения в вашем браузере

На эту тему уже есть несколько хороших ответов (я только что нашел их в Google), поэтому для браузеров, где это возможно, я приведу относительный ответ. Однако помните, что отключение политики того же источника (или CORS) повлияет только на ваш браузер . Кроме того, запуск браузера с отключенными настройками безопасности для того же Origin обеспечивает любой доступ к веб-сайту к ресурсам между источниками, поэтому это очень небезопасно и должно быть сделано только для целей разработки .

657
Marco Bonelli

В дополнение к ответу Марко Бонелли: лучший современный способ взаимодействия между фреймами/iframes - это window.postMessage , поддерживается всеми браузерами

46
Geert

Проверьте веб-сервер домена для конфигурации http://www.<domain>.com для X-Frame-Options. Это функция безопасности, разработанная для предотвращения атак clickJacking,

Как работает ClickJacking?

  1. Злая страница выглядит точно так же, как страница жертвы.
  2. Затем он обманул пользователей, чтобы ввести их имя пользователя и пароль.

Технически у зла есть 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>

Как работает функция безопасности

Если вы хотите, чтобы запрос веб-сервера не обрабатывался внутри iframe, добавьте x-frame-options

X-Frame-Options DENY

Варианты:

  1. SAMEORIGIN // разрешить только моему собственному домену отображать мой HTML внутри iframe.
  2. DENY // не разрешаем отображать мой HTML внутри любого iframe
  3. "ALLOW-FROM https://example.com/ " // разрешить конкретному домену отображать мой HTML внутри iframe

Это IIS пример конфигурации:

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

Решение вопроса

Если веб-сервер активировал функцию безопасности, это может вызвать клиентскую ошибку SecurityError, как и должно быть.

13
Shahar Shokrani

Для меня я хотел реализовать двухстороннее рукопожатие, что означает:
- родительское окно будет загружаться быстрее, чем iframe
- iframe должен общаться с родительским окном, как только оно будет готово
- родитель готов получить сообщение iframe и повторить

этот код используется для установки белой метки в iframe с помощью [Пользовательское свойство CSS]
код:
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","*");
    }
});

родитель

$(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]

7
Yakir Manor