Ich habe ein Projekt, in dem ich ein <iframe> -Element mit JavaScript erstellen und an das DOM anhängen muss. Danach muss ich einige Inhalte in den <iframe> einfügen. Es ist ein Widget, das in Websites von Drittanbietern eingebettet wird.
Ich setze das Attribut "src" des <iframe> nicht, da ich keine Seite laden möchte. Vielmehr wird es verwendet, um den Inhalt, den ich einfüge, zu isolieren / zu boxen, damit ich nicht auf CSS- oder JavaScript-Konflikte mit der übergeordneten Seite stoße. Ich verwende JSONP, um HTML-Inhalte von einem Server zu laden und in diesen <iframe> einzufügen.
Ich habe diese Funktion einwandfrei, mit einer schwerwiegenden Ausnahme - wenn die Eigenschaft document.domain auf der übergeordneten Seite festgelegt ist (was in bestimmten Umgebungen der Fall sein kann, in denen dieses Widget bereitgestellt wird), Internet Explorer (wahrscheinlich alle Versionen, aber ich habe Bestätigt in 6, 7 und 8) gibt mir den Fehler "Zugriff verweigert", wenn ich versuche, auf das Dokumentobjekt dieses von mir erstellten <iframe> zuzugreifen. Es passiert nicht in anderen Browsern, in denen ich getestet habe (alle wichtigen modernen).
Dies ist sinnvoll, da mir bekannt ist, dass Sie in Internet Explorer die document.domain aller Fenster / Frames, die miteinander kommunizieren, auf denselben Wert setzen müssen. Mir ist jedoch keine Möglichkeit bekannt, diesen Wert für ein Dokument festzulegen, auf das ich nicht zugreifen kann.
Ist jemandem eine Möglichkeit bekannt, dies zu tun - irgendwie die document.domain-Eigenschaft dieses dynamisch erstellten <iframe> festlegen? Oder betrachte ich es nicht aus dem richtigen Winkel - gibt es einen anderen Weg, um das zu erreichen, was ich will, ohne auf dieses Problem zu stoßen? Ich muss auf jeden Fall einen <iframe> verwenden, da das isolierte / Sandbox-Fenster für die Funktionalität dieses Widgets von entscheidender Bedeutung ist.
Hier ist mein Testcode:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Document.domain Test</title>
<script type="text/javascript">
document.domain = 'onespot.com'; // set the page's document.domain
</script>
</head>
<body>
<p>This is a paragraph above the <iframe>.</p>
<div id="placeholder"></div>
<p>This is a paragraph below the <iframe>.</p>
<script type="text/javascript">
var iframe = document.createElement('iframe'), doc; // create <iframe> element
document.getElementById('placeholder').appendChild(iframe); // append <iframe> element to the placeholder element
setTimeout(function() { // set a timeout to give browsers a chance to recognize the <iframe>
doc = iframe.contentWindow || iframe.contentDocument; // get a handle on the <iframe> document
alert(doc);
if (doc.document) { // HEREIN LIES THE PROBLEM
doc = doc.document;
}
doc.body.innerHTML = '<h1>Hello!</h1>'; // add an element
}, 10);
</script>
</body>
</html>
Ich habe es gehostet bei:
http://troy.onespot.com/static/access_denied.html
Wie Sie sehen werden, wenn Sie diese Seite in IE laden, habe ich an dem Punkt, an dem ich alert () aufrufe, ein Handle für das Fensterobjekt des <iframe>. Ich kann einfach nicht tiefer in sein Dokumentobjekt eindringen.
Vielen Dank für jede Hilfe oder Anregungen! Ich bin jedem zu Dank verpflichtet, der mir helfen kann, eine Lösung dafür zu finden.
Antworten:
Seufzer. Ja, es ist ein IE-Problem (Fehler? Schwer zu sagen, da es keinen dokumentierten Standard für diese Art von Unannehmlichkeit gibt). Wenn Sie einen srcless-Iframe erstellen, erhält dieser einen
document.domain
vom übergeordneten Dokumentlocation.host
anstelle seinesdocument.domain
. Zu diesem Zeitpunkt haben Sie so ziemlich verloren, da Sie es nicht ändern können.Eine schreckliche Problemumgehung besteht darin
src
, ein Javascript festzulegen: URL (urgh!):iframe.src= "javascript:'<html><body><p>Hello<\/p><script>do things;<\/script>'";
Aus irgendeinem Grund kann ein solches Dokument
document.domain
im IE kein eigenes Skript festlegen (guter alter „nicht angegebener Fehler“), sodass Sie damit keine Brücke zwischen dem übergeordneten Dokument (*) wiederherstellen können. Sie können damit das gesamte Dokument-HTML schreiben, vorausgesetzt, das Widget muss nach der Instanziierung nicht mehr mit dem übergeordneten Dokument kommunizieren.Allerdings funktionieren iframe-JavaScript-URLs in Safari nicht, sodass Sie immer noch eine Art Browser-Sniffing benötigen, um die zu verwendende Methode auszuwählen.
*: Aus irgendeinem anderen Grunde, Sie können , in IE, gesetzt
document.domain
von einem zweiten Dokument, document.written durch das erste Dokument. Das funktioniert also:if (isIE) iframe.src= "javascript:'<script>window.onload=function(){document.write(\\'<script>document.domain=\\\""+document.domain+"\\\";<\\\\/script>\\');document.close();};<\/script>'";
Zu diesem Zeitpunkt ist die Scheußlichkeit zu hoch für mich, ich bin raus. Ich würde das externe HTML machen, wie David sagte.
quelle
void()
Aufruf wahrscheinlich auch verlieren , da die Funktion bereits zurückkehrtundefined
.Ja, die Zugriffsausnahme ist auf die Tatsache zurückzuführen, dass
document.domain
sie in Ihrem Elternteil und Ihrem Iframe übereinstimmen muss. Bevor dies der Fall ist, können Sie diedocument.domain
Eigenschaft Ihres Iframes nicht programmgesteuert festlegen .Ich denke, Ihre beste Option hier ist es, die Seite auf eine eigene Vorlage zu verweisen:
iframe.src = '/myiframe.htm#' + document.domain;
Und in myiframe.htm:
document.domain = location.hash.substring(1);
quelle
Nun, ich habe tatsächlich ein sehr ähnliches Problem, aber mit einer Wendung ... sagen wir, die Top-Level-Site ist a.foo.com - jetzt setze ich die Dokumentdomäne auf a.foo.com
dann setze ich es in dem iframe, den ich erstelle / besitze, auch auf a.foo.com
Beachten Sie, dass ich sie nicht zu foo.com b / c setzen kann. Es gibt einen anderen Iframe auf der Seite, der auf bafoo.com verweist (der wiederum a.foo.com verwendet, aber ich kann den Skriptcode dort nicht ändern).
Sie werden bemerken, dass ich document.domain im Wesentlichen auf das setze, was es ohnehin schon sein würde ... aber ich muss das tun, um auf den anderen Iframe zuzugreifen, den ich von bafoo.com erwähnt habe
In meinem Frame wird nach dem Festlegen der Domain, obwohl alle Iframes dieselbe Einstellung haben, immer noch eine Fehlermeldung angezeigt, wenn ich in IE 6/7 auf das übergeordnete Element zugegriffen habe
Es gibt andere Dinge, die wirklich bizaree sind
Wenn ich in der Außen- / obersten Ebene auf das Onload-Ereignis warte und einen Timer einstelle, kann ich schließlich in den Frame greifen, auf den ich zugreifen muss ... aber ich kann nie von unten nach oben greifen ... und das wirklich müssen in der Lage sein
auch wenn ich alles auf foo.com setze (was ich, wie gesagt, nicht kann), FUNKTIONIERT ES! aber aus irgendeinem Grund, wenn der gleiche Wert wie location.host verwendet wird ... tut es nicht und es bringt mich um ...
quelle
Ich benutze nur
<iframe src="about:blank" ...></iframe>
und es funktioniert gut.quelle
Für IE ist der Port wichtig. Zwischen den Domänen sollte es sich um denselben Port handeln.
quelle
Haben Sie jQuery.contents () ausprobiert ?
quelle
Es scheint, dass das Problem mit dem Internet Explorer auftritt, wenn Sie versuchen, über das document.frames-Objekt auf den Iframe zuzugreifen. Wenn Sie einen Verweis auf den erstellten Iframe in einer Variablen speichern, können Sie über die Variable (my_iframe im folgenden Code) auf den injizierten Iframe zugreifen ).
Ich habe dies in IE6 / 7/8 zum Laufen gebracht
var my_iframe; var iframeId = "my_iframe_name" if (navigator.userAgent.indexOf('MSIE') !== -1) { // IE wants the name attribute of the iframe set my_iframe = document.createElement('<iframe name="' + iframeId + '">'); } else { my_iframe = document.createElement('iframe'); } iframe.setAttribute("src", "javascript:void(0);"); iframe.setAttribute("scrolling", "no"); iframe.setAttribute("frameBorder", "0"); iframe.setAttribute("name", iframeId); var is = iframe.style; is.border = is.width = is.height = "0px"; if (document.body) { document.body.appendChild(my_iframe); } else { document.appendChild(my_iframe); }
quelle
Ich hatte ein ähnliches Problem und meine Lösung war dieses Code-Snippet (getestet in IE8 / 9, Chrome und Firefox).
var iframe = document.createElement('iframe'); document.body.appendChild(iframe); iframe.src = 'javascript:void((function(){var script = document.createElement(\'script\');' + 'script.innerHTML = "(function() {' + 'document.open();document.domain=\'' + document.domain + '\';document.close();})();";' + 'document.write("<head>" + script.outerHTML + "</head><body></body>");})())'; iframe.contentWindow.document.write('<div>foo</div>');
Ich habe verschiedene Methoden ausprobiert, aber diese schien die beste zu sein. Einige Erklärungen finden Sie in meinem Blogbeitrag hier .
quelle
Nach der äußerst einfachen Methode von Andralor wurde das Problem für mich behoben: https://github.com/fancyapps/fancyBox/issues/766
Rufen Sie den iframe im Wesentlichen am Update erneut auf:
$('a.js-fancybox-iframe').fancybox({ type: 'iframe', scrolling : 'visible', autoHeight: true, onUpdate: function(){ $("iframe.fancybox-iframe"); } });
quelle
IE funktioniert mit iframe wie alle anderen Browser (zumindest für Hauptfunktionen). Sie müssen nur eine Reihe von Regeln einhalten:
Wenn alle Iframe-Ressourcen geladen sind, ändern Sie die Datei document.domain so, dass sie mit der im übergeordneten Element definiert ist. (Sie müssen dies später tun, da das Festlegen der Domäne dazu führt, dass die Anforderung der Iframe-Ressource fehlschlägt.)
Jetzt können Sie eine Referenz für das übergeordnete Fenster erstellen: var winn = window.parent
quelle
Für mich war die bessere Antwort, die Dateiberechtigungen zu überprüfen, auf die der Zugriff verweigert wird.
Ich habe gerade auf jQuery-1.8.0.js aktualisiert und in IE9 den Fehler "Zugriff verweigert" erhalten.
Aus dem Windows Explorer
Hat die Seite getestet. Kein Problem mehr.
Ich musste dasselbe für das jQuery-UI-Skript tun, das ich gerade aktualisiert hatte
quelle