it-swarm.com.de

Fehler: Zugriff auf Eigenschaft "Dokument" verweigert

Ich habe ein HTML-Dokument, das ein iframe enthält. Immer wenn ich versuche, mit JS auf dieses iframe zuzugreifen oder es zu ändern, erhalte ich Error: Permission denied to access property "document".

Ich benutze frame.contentWindow.document.body.innerHTML oder frame.contentWindow.document.body.onload oder ähnliche Attribute, um auf das iframe zuzugreifen oder es zu ändern. (In dem gegebenen Code wird das iframe als frame bezeichnet.)

Für die Web-App, die ich entwickle, ist der Zugriff auf diese Attribute erforderlich. Auf diese (oder ähnliche) Alternativen kann ich nicht verzichten.

21
sbrm1

Sie können dieses Problem mit Hilfe von YQL umgehen, obwohl Sie keinen Zugriff auf den Header-Teil des Empfangsfensters haben. Bei der Postmessage-Methode müssen Sie auch das Skript des Empfängerfensters bearbeiten. Mit dieser Methode können Sie jedoch jeden iframe laden, ohne dessen Skripte zu berühren. Überprüfen Sie dies heraus!

<html>
<iframe src="https://google.com/" width="500" height="300"></iframe>

<script>
var iframe = document.getElementsByTagName('iframe')[0];
var url = iframe.src;
var getData = function (data) {
    if (data && data.query && data.query.results && data.query.results.resources && data.query.results.resources.content && data.query.results.resources.status == 200) loadHTML(data.query.results.resources.content);
    else if (data && data.error && data.error.description) loadHTML(data.error.description);
    else loadHTML('Error: Cannot load ' + url);
};
var loadURL = function (src) {
    url = src;
    var script = document.createElement('script');
    script.src = 'https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20data.headers%20where%20url%3D%22' + encodeURIComponent(url) + '%22&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=getData';
    document.body.appendChild(script);
};
var loadHTML = function (html) {
    iframe.src = 'about:blank';
    iframe.contentWindow.document.open();
    iframe.contentWindow.document.write(html.replace(/<head>/i, '<head><base href="' + url + '"><scr' + 'ipt>document.addEventListener("click", function(e) { if(e.target && e.target.nodeName == "A") { e.preventDefault(); parent.loadURL(e.target.href); } });</scr' + 'ipt>'));
    iframe.contentWindow.document.close();
}

loadURL(iframe.src);
</script>
</html>
8
Gihan Gamage

Das Aufrufen und Ändern von Webseiten in iframes anderer Websites wird als Cross-Site-Scripting oder bezeichnet XSS und es ist eine Technik, mit der böswillige Hacker ahnungslosen Opfern auf die Spur kommen.

Eine Richtlinie mit dem Namen "Same-Origin Policy" wird von Browserherstellern implementiert, um ein solches Verhalten und die willkürliche Ausführung von JS-Code zu verhindern.

Dieser Fehler kann verhindert werden, indem das übergeordnete Dokument und das Dokument in iframe in derselben Domäne und Unterdomäne gehostet werden und sichergestellt wird, dass die Dokumente mit demselben Protokoll geladen werden.

Beispiele für inkompatible Seiten:

  1. http://www.example.org & http://www.example2.com
  2. http://abc.example.org & http://xyz.example.com
  3. http://www.example.org & https://www.example.com

Cross-Origin Resource Sharing ist eine Lösung für dieses Problem.

Beispielsweise:
Wenn http://www.example.comhttp://www.example.com/hello Mit http://www.example.org Teilen möchte, kann ein Header mit dem Dokument gesendet werden, der wie folgt aussieht:

Access-Control-Allow-Origin: http://www.example.org

Um es mit HTML zu senden, geben Sie es einfach in ein <META HTTP-EQUIV="..."> - Tag ein:

<head>
    ...
    <META HTTP-EQUIV="Access-Control-Allow-Origin" CONTENT="http://www.example.org">
    ...
</head>
20
sbrm1

Sie können postMessage verwenden

Fenster 1 - Empfangen

window.addEventListener("message", receiveMessage, false);

function receiveMessage(event)
{
  var Origin = event.Origin || event.originalEvent.Origin; 
  // For Chrome, the Origin property is in the event.originalEvent object.
  if (Origin !== "http://example.org:8080")
    return;

  // ...
}

Fenster - 2 Senden

var popup = window.open(...popup details...);
popup.postMessage(
       "The user is 'bob' and the password is 'secret'", 
       "https://secure.example.net"
);

Sie müssen ein weiteres Paar erstellen, um miteinander zu kommunizieren.

9
joyBlanks