it-swarm.com.de

SecurityError: Verhindert, dass ein Frame mit Origin auf einen Cross-Origin-Frame zugreift

Ich lade einen <iframe> in meine HTML-Seite und versuche, mit Javascript auf die darin enthaltenen Elemente zuzugreifen. Beim Versuch, meinen Code auszuführen, wird jedoch die folgende Fehlermeldung angezeigt:

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

Können Sie mir bitte helfen, eine Lösung zu finden, damit ich auf die Elemente im Rahmen zugreifen kann?

Ich benutze diesen Code zum Testen, aber vergebens:

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

Same-Origin-Richtlinie

Nicht zu verwechseln mit CORS !

Sie können mit JavaScript nicht auf einen <iframe> mit unterschiedlichem Ursprung zugreifen. Dies wäre eine große Sicherheitslücke, wenn Sie dies tun könnten. Für die same-Origin-Richtlinie -Browser werden Skripts blockiert, die versuchen, auf einen Frame mit einem anderen Ursprung zuzugreifen .

Origin wird als anders angesehen, wenn mindestens einer der folgenden Teile der Adresse nicht gepflegt ist:

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

Protokoll , Hostname und Port muss mit Ihrer Domain identisch sein, wenn Sie auf einen Frame zugreifen möchten.

Beispiele

Folgendes würde passieren, wenn Sie versuchen, über http://www.example.com/home/index.html auf die folgenden URLs zuzugreifen:

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

Obwohl die Same-Origin-Richtlinie den Zugriff von Skripten auf den Inhalt von Websites mit einem anderen Ursprung blockiert , können Sie dieses Problem mit window.postMessage umgehen, wenn Sie beide Seiten besitzen und sein relatives message -Ereignis , um Nachrichten zwischen den beiden Seiten zu senden:

  • In Ihrer Hauptseite:

    let frame = document.getElementById('your-frame-id'); 
    
    frame.contentWindow.postMessage(/*any variable or object here*/, '*'); 
    
  • In Ihrem <iframe> (auf der Hauptseite enthalten):

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

Diese Methode kann in beide Richtungen angewendet werden , wobei auch auf der Hauptseite ein Listener erstellt wird und Antworten vom Frame empfangen werden. Dieselbe Logik kann auch in Popups und im Grunde in jedem neuen Fenster implementiert werden, das von der Hauptseite generiert wird (z. B. mit window.open() ), ohne Unterschied.

Deaktivieren der Same-Origin-Richtlinie in Ihrem Browser

Es gibt bereits einige gute Antworten zu diesem Thema (ich habe sie gerade als googelnd empfunden). Für die Browser, in denen dies möglich ist, verknüpfe ich die relative Antwort. Denken Sie jedoch daran, dass das Deaktivieren der Same-Origin-Richtlinie (oder des CORS) nur Ihren Browser betrifft . Wenn Sie einen Browser mit deaktivierten Sicherheitseinstellungen von Origin ausführen, wird jeder Website-Zugriff auf Cross-Origin-Ressourcen gewährt, sodass der Zugriff sehr unsicher ist und sein sollte Nur für Entwicklungszwecke .

691
Marco Bonelli

Ergänzend zu Marco Bonellis Antwort: Die derzeit beste Art der Interaktion zwischen Frames/Iframes ist die Verwendung von window.postMessage , von allen Browsern unterstützt

49
Geert

Überprüfen Sie den Webserver der Domain auf http://www.<domain>.com Konfiguration auf X-Frame-Options Es handelt sich um eine Sicherheitsfunktion, die ClickJacking-Angriffe verhindert.

Wie funktioniert Clickjacking?

  1. Die böse Seite sieht genauso aus wie die Opferseite.
  2. Dann wurden Benutzer dazu gebracht, ihren Benutzernamen und ihr Passwort einzugeben.

Technisch gesehen hat das Böse ein iframe mit der Quelle zur Opferseite.

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

Wie das Sicherheitsmerkmal funktioniert

Wenn Sie verhindern möchten, dass eine Webserveranforderung in einem iframe gerendert wird, fügen Sie die x-frame-options hinzu

X-Frame-Optionen VERWEIGERN

Die Optionen sind:

  1. SAMEORIGIN // erlaube nur meiner eigenen Domain, mein HTML in einem iframe zu rendern.
  2. DENY // erlaube nicht, dass mein HTML in einem iframe gerendert wird
  3. "ALLOW-FROM https://example.com/ " // Bestimmte Domain darf mein HTML in einem iframe rendern

Dies ist das IIS Konfigurationsbeispiel:

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

Die Lösung der Frage

Wenn der Webserver die Sicherheitsfunktion aktiviert hat, kann dies einen clientseitigen SecurityError verursachen.

16
Shahar Shokrani

Für mich wollte ich einen 2-Wege-Handshake implementieren, was bedeutet:
- Das übergeordnete Fenster wird schneller geladen als der Iframe
- Der Iframe sollte mit dem übergeordneten Fenster sprechen, sobald es fertig ist
- Der Elternteil ist bereit, die Iframe-Nachricht zu empfangen und zu wiederholen

dieser Code wird verwendet, um das White Label im Iframe mit [CSS custom property] festzulegen
Code:
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","*");
    }
});

Elternteil

$(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);
});

natürlich können Sie die Herkunft und den Text einschränken, dies ist einfach mit Code zu arbeiten
Ich fand dieses Beispiel hilfreich:
[Domainübergreifendes Messaging mit postMessage]

7
Yakir Manor