Zunächst ist die Iframe-Kommunikation unterteilt in: gleichdomänen Kommunikation und Cross-Domänen-Kommunikation.
1. Kommunikation in derselben Domäne
Die sogenannte Kommunikation mit gleichdomänen bezieht
Zum Beispiel: <iframe src = "http: //localhost/demo/iframe/iframeb.html" id = "iframea" name = "iframea"> Die Daten dieser beiden Seiten kommunizieren. Ich möchte beispielsweise die Funktion auf der Kinderseite auf der übergeordneten Seite A.HTML aufrufen, was für uns leicht an document.getElementById('iframeA').contentWindow.b(); Unter Google, wobei B eine Funktion auf der Kinderseite b.html ist. Aber es gibt ein Problem mit diesem Anruf, mit dem ich schon lange zu kämpfen habe, da ich wie folgt einen solchen Fehler unter Firefox gemeldet habe:
B ist keine Funktion, aber ich habe eine solche Funktion auf der Unterseite klar definiert. Warum tritt ein solcher Fehler also auf? Nach sorgfältiger Analyse und Google stellte ich fest, dass es ein Problem gibt, das verstanden werden muss. Wenn der Iframe nicht geladen wurde, werde ich diesen JS ausführen und einen solchen Fehler melden. Also habe ich versucht, die Funktion iframe.onload unter Firefox zu verwenden, um sie zu testen. Sicher genug, es gab keinen Fehler, es war richtig, also war ich mir sicher, dass es dieses Problem war. Ich möchte also einen kompatiblen IE und Firefox Google schreiben, um eine Funktion zu schreiben, um zu bestätigen, dass das Iframe geladen wurde! Geben Sie in der Tat eine Rückruffunktion an, um unsere obige Methode aufzurufen.
Basierend auf den obigen Ideen können Sie einen Code wie diesen schreiben:
<iframe src = "http: //localhost/demo/iframe/iframeb.html" id = "iframea" name = "iframea"> </iframe> <div id="topName">topNdddddddddddddddddddddddddddddddddddddddddd</div> <script> function A(){ alert("A"); } var iframe = document.getElementById ('iframea'); IfrAmeisLoad (iframe, function () {var obj = document.getElementById ('iframea'). contentWindow; obj.b ();}); function iframeIsLoad (iframe, callback) {if (iframe.attachEvent) {iframe.attachEvent ('onload', function () {callback && callback ();}); } else {iframe.onload = function () {callback && callback (); }}}} </script>Der B.html -Code lautet wie folgt:
var b = function () {alert ("b"); } Es ist sehr einfach, die Funktion der übergeordneten Seite auf der Kinderseite aufzurufen. Mach das einfach und es wird in Ordnung sein, window.parent.A();
Die untergeordnete Seite nimmt den Wert des übergeordneten Seitenelements an: window.parent.document.getElementById("topName").innerHTML und andere Methoden.
Zwei: Iframe Cross-Domain-Kommunikation.
Der Zugang von Iframe-Cross-Domänen ist im Allgemeinen in zwei Situationen unterteilt. Die erste ist die Kreuzung mit derselben Hauptdomäne und verschiedenen Subdomänen. Der zweite Typ ist: verschiedene Hauptdomänen kreuzen Domänen.
1. Es ist eine Kreuzdomäne zwischen verschiedenen Subdomänen unter derselben Hauptdomäne; Es kann gelöst werden, indem die gleiche Hauptdomäne über das Dokument festgelegt wird. Domäne.
Wenn ich eine Domäne abc.example.com habe, gibt es eine Seite namens Abc.html, und ein Iframe ist auf der Seite verpflichtet wie folgt: <iframe src = "http://def.example.com/def.html" iframe2 "style 2". Seite ABC.HTML Wir alle wissen, dass JS aufgrund der Einschränkungen der gleichorientierten Richtlinie des Sicherheitsbrowsers keine Seiten mit verschiedenen Ports unter verschiedenen Protokollen unter verschiedenen Domänen betreiben kann, sodass der Cross-Domänen-Zugriff gelöst wird. Wenn die übergeordnete Seite abc.html eine JS -Funktion hat: function test(){console.log(1);}; Ich möchte diese Funktion auf der Unterseite aufrufen oder parent.test(); Auf diese Weise besteht die Lösung durch die Betrachtung der Cross-Domain unter Firefox darin, ein document.domain = 'example.com' hinzuzufügen.
Der ABC.HTML -Code lautet wie folgt:
<iframe src = "http://def.example.com/demo/def.html" id = "iframe2" style = "display: keine;
Der Def.html -Code lautet wie folgt:
/** Die Methode der untergeordneten Seite, die die übergeordnete Seite aufruft*/document.domain = 'example.com'; // window.top.test (); window.parent.test ();
Oder auf diesen beiden Seiten möchte ich, dass die übergeordnete Seite die untergeordnete Seite wie folgt aufruft:
Der HTML -Code ist wie folgt:
/** Funktionen, die untergeordnete Seiten über die übergeordnete Seite von Domain aufrufen möchten. if (iframe.attachEvent) {iframe.attachEvent ('onload', function () {callback && callback ();}); } else {iframe.onload = function () {callback && callback (); }}}}Wenn auf der Seite def.html nun einen untergeordneten Funktionscode vorhanden ist:
document.domain = 'example.com'; function chirt () {console.log ('Ich bin eine untergeordnete Seite');}Sie können über Domains hinweg anrufen, unabhängig davon, ob es sich um eine untergeordnete Seite handelt, die die übergeordnete Seite oder eine übergeordnete Seite auf der Seite der untergeordneten Seite aufruft. Alles ist in Ordnung!
2. Es sind unterschiedliche Hauptdomänen und Querdomänen;
Obwohl Google über verschiedene Methoden für Cross-Domain-Probleme in verschiedenen Hauptdomänen verfügt, einschließlich location.hash -Methode, window.name -Methode, HTML5 und Flash usw., denke ich, dass die folgende IFRame-Methode es wert ist, gelernt zu werden.
As shown in the figure below: The page request.html of domain a.com (i.e. http://a.com/demo/ajax/ajaxproxy/request.html) is nested with an iframe pointing to domain b.com (http://b.com/demo/ajaxproxy/response.html), and the proxy.html of domain A.com ist mit dem Proxy.html der Domain A.com verschachtelt.
Idee: Um die Seite von Request.html unter dem A.com -Domänenanforderungsprozess zu implementieren.php unter der Domain B.Com zu implementieren, können Sie den Anforderungsparameter an die Antwort über die URL übergeben und eine echte AJAX -Anforderung initiieren. Da Proxy.html und Request.html in derselben Domäne sind, können Sie das window.top verwenden, um das Ergebnis in Request.html zurückzugeben, um die reale Kreuzdomäne zu vervollständigen.
Ok, schauen wir uns zuerst die Seitenstruktur an
Unter der A.com -Domäne gibt es:
Request.html
Proxy.html
Unter der Domain von b.com gibt es:
response.html
process.php
Schauen wir uns wie folgt die Seite an.
<! DocType html> <html> <kopf> <titels> Neues Dokument </title> </head> <body> <p id = "result"> Das Antwortergebnis wird hier ausgefüllt. style = "display: keine"> </iframe> <cript> document.getElementById ('sendBtn'). onclick = function () {var url = 'http://b.com/demo/ajax/ajaxproxy/reponse.html', fn = ajax/ajaxproxy/reponse.html ', GetPerson', /////// // //// // // //s is the methode in Answer ist in Answersantrieb. 24} ', // Dies ist der angeforderte Parameter Callback = "Callback"; // Dies ist die Rückruffunktion, die nach Abschluss des gesamten Anforderungsprozesses ausgeführt wurde und die letzte Aktion CrossRequest (URL, FN, Reqdata, Callback) ausführt. // eine Anforderung} Funktion CrossRequest (URL, FN, Reqdata, Callback) {var server = document.getElementById ('serverif'); server.src = url + '? fn =' + cododeuricomponent (fn) + "& data =" + codericomponent (reqdata) + "& callback =" + cododeuricomponent (Callback); } // Rückruffunktionsfunktion Rückruf (Daten) {var str = "Mein Name ist" + data.name + ". Ich bin ein" + data.sex + ". Ich bin" + data.age + Jahre alt. "; document.getElementById ("Ergebnis"). InnerHtml = str; } </script> </body> </html> Bei dieser Seite geht es tatsächlich darum GetPerson Antwort zu erzählen. response.html ist rein verantwortlich für die Übergabe des Methodennamen CallBack an den nächsten Bruder proxy.html. proxy.html kann es nach dem Erhalten des Method -Namens CallBack ausführen, da Proxy.html und Request.html in derselben Domäne sind.
Der Code der Antwort.html lautet wie folgt:
<! DocType html> <html> <kopf> <titels> Neues Dokument </title> </head> <body> <Iframe id = "proxy"> </iframe> <script> // Allgemeine Methode AJAX -Anforderungsfunktion _request (reqdata, url, Callback) {var xmlhttp; if (window.xmlhttprequest) {xmlhttp = new XmlHttpRequest (); } else {xmlhttp = new ActiveXObject ("microsoft.xmlhttp"); } xmlhttp.onReadyStatechange = function () {if (xmlhttp.ReadyState == 4 && xmlhttp.status == 200) {var data = xmlhttp.responSeText; Rückruf (Daten); }} xmlhttp.open ('post', url); xmlhttp.setRequestheader ("Content-Typ", "application/json; CharSet = utf-8"); xmlhttp.send (reqdata); } // Allgemeine Methode, um URL -Parameterfunktion zu erhalten. Rückgabewert; } // AJAX -Anforderung an process.php function getPerson (reqdata, radback) {var url = 'http://b.com/demo/ajax/ajaxproxy/process.php'; var fn = function (data) {var proxy = document.getElementById ('proxy'); proxy.src = "http://a.com/demo/ajax/ajaxproxy/proxy.html?data=" + cododeuricomponent (data) + "& callback =" + cododeuricomponent (Rückruf); }; _Request (reqdata, url, fn); } (function () {var fn = _getQuery ('fn'), reqdata = _getQuery ("data"), callback = _getQuery ("Callback"); eval (fn + "('" + reqdata + "'," + callback + ")"); </script> </body> </html>Dies soll die Anfrage von Request.html erhalten und die Anforderungsparameter und -methoden abrufen, dann eine echte AJAX -Anforderung an den Serverprozess.php ausstellen und dann die vom Server zurückgegebenen Daten und den von Request.html an Proxy.html übergebenen Callback -Funktionsnamen übergeben.
Schauen wir uns als nächstes den PHP -Code wie folgt an , der eigentlich nur die Rückgabe einer JSON -Daten zurückgibt:
<? php $ data = json_decode (file_get_contents ("php: // input")); Header ("Content-Type: Application/JSON; CharSet = UTF-8"); echo ('{"id":'. $ data-> id.Schließlich gibt es den Proxy.html -Code:
<! DocType html> <html> <kopf> <titels> Neues Dokument </title> </head> <body> <Script> Funktion _geturl (Schlüssel) {// Allgemeine Methode, Get URL -Parameter var query = location "=") [1] .Split ("&") [0]); Rückgabewert; } (function () {var callback = _geturl ("callback"), data = _geturl ("data"); eval ("window.top." + decodeuricomponent (callback) + "(" + decodeuricomponent (data) + ")");}) (); </script> </body> </html>Dies ist auch der letzte Schritt. Proxy hat schließlich den Namen der Rückruffunktion von Request.html über Antwort.html und die direkt von Antwort.html übertragenen Antwortdaten übertragen und verwendete das Fenster.
3.. Das Problem der hohen Anpassungsfähigkeit von IFrames.
Die Anpassung der Iframe -Höhenanpassung ist in zwei Typen unterteilt: Eine ist die Anpassung unter derselben Domäne und die andere ist die Anpassung unter der Kreuzdomäne . Schauen wir uns das Problem der hohen Anpassung im selben Bereich an.
1. Probleme mit hoch anpassungsfähigen Iframes in derselben Domäne:
Idee: Holen Sie sich das verschachtelte Iframe -Element, erhalten Sie die endgültige Höhe der verschachtelten Seite über JavaScript und setzen Sie es dann auf der Hauptseite, um dies zu erreichen.
Wenn unsere Demo iframe1.html und iframe2.html hat
Das Folgende ist der folgende Code:
<! DocType html> <html> <kopf> <titels> Neues Dokument </title> <style> *{Margin: 0; Padding: 0;} </style> </head> <body> <Iframe src = "http://a.com/demo/ajax/iframhigh/iframe1.htm2.htm. id = "iframe"> </iframe> <skript> Fenster.onload = function () {var iframeid = document.getElementById ('iframe'); if (iframeid &&! window.opera) {if (iframeid.contentdocument && iframeid.contentDocument } else if (iframeid.document && iframeid.document.body.scrollHeight) {iframeid.height = iframeid.document.body.scrollHeigh; }}} </script> </body> </html>Iframe2.html
<! DocType html> <html> <kopf> <titels> Neues Dokument </title> <style> *{Margin: 0; Padding: 0;} </style> </head> <body> <div style = "Höhe: 500px;"> </body> </html> </html>Sie können die Höhe der IFrame1 -Seite dynamisch auf iFrame2 Höhe einstellen.
2. Iframes sind in den Domänen sehr anpassbar.
Zunächst wissen wir, dass wir die Kreuzdomäne von IFrames mit der obigen JS-Methode nicht kontrollieren können, sodass wir nur die Zwischentaste verwenden können, um eine IFrame2.html-Seite unter der Domäne der B.Com-Domäne auf der iFrame1.html-Seite unter der gleiche Domain A.com-Seite mit IFRAME1.html auf der iFrame3.html-Seite zu nisten. Auf diese Weise können IFrame1.html und Iframe3.html ohne Hindernisse kommunizieren, da die Seite iframe2.html Iframe3.html nistet, also kann Iframe2.html den HREF -Wert von iframe3.html umschreiben.
Inhalt in Iframe1:
Der Inhalt von iframe1.html akzeptiert hauptsächlich den von der Seite iframe3.html übertragenen Inhalt und vervollständigt den entsprechenden Vorgang. Der Code iframe1.html lautet wie folgt:
<iframe src = "http://b.com/demo/ajax/iframeheigh/iframe2.html" id = "iframe"> </iframe> <script> var ifr_el = document.getElementById ("iframe"); Funktion getifrData (data) {ifr_el.style.height = data+"px"; } </script>Inhalt in Iframe2.html:
Wie übergibt der Inhalt iframe2.html den Wert an die Seite iframe3.html? Ich habe nur gesagt, dass der Wert an die HREF der Seite iframe3.html übergeben wird. Ändern Sie also einfach die SRC des IFrame. Da die C -Seite nicht aktualisiert werden muss, kann sie von Hash an die Seite iframe3.html übergeben werden. Der Code von iframe2.html lautet wie folgt:
<!DOCTYPE HTML><html> <head> <title> New Document </title> <style> *{margin:0;padding:0;} </style> </head> <body> <iframe id="iframe" src="http://a.com/demo/ajax/iframeheight/iframe3.html"></iframe> <script> var oldHeight = 0, ifr_el = document.getElementById ("iframe"); T && ClearInterval (t); var t = setInterval (function () {var height = document.body.scrollHeight; if (OldHeight! = Höhe) {OldHeight = Höhe; ifr_el.src += '#' +OldHeight;}}, 200); </script> </body> </html>Sie können feststellen, dass die Höhe der IFrame1.html -Seite i iframe2.html 200 Pixel beträgt. Jetzt möchte ich die Höhe des Scroll -Balkens in Iframe2.html erhalten, die Höhe über Iframe3.html an den SRC übergeben und dann den Höhenwert in der Seite iframe3.html erhalten, um es an Iframe1.html zu übergeben (weil iframe1.html und iframe3.html. Höhe selbst ist es in Ordnung.
Die einzige Funktion der Seite iframe3.html besteht darin, den von der Seite iframe2.html über die HREF übergebenen Wert zu empfangen und an die Seite iframe1.html weiterzugeben. Der an die Seite iframe2.html übergebene Wert kann kontinuierlich über einen Timer überprüft werden, um festzustellen, ob der Ort geändert wurde. Das fühlt sich jedoch sehr ineffizient an. Eine andere Möglichkeit besteht darin, auf die Änderungen von HREF durch onhashchange -Ereignis (IE8+, Chrome5.0+, Firefox3.6+, Safari5.0+, Opera10.6+) im neuen Browser zuzuhören.
Der Code iframe3.html lautet wie folgt:
<Script> var oldHeight = 0; T && ClearInterval (t); var t = setInterval (function () {var height = location.href.split ('#') [1]; if (Höhe && Höhe! </script>Dies kann das Problem lösen, die Höhe der Iframe-Anpassungsfähigkeit durch Cross-Domain zu erreichen.
4. Zusammenfassung
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, es wird für das Studium und die Arbeit aller hilfreich sein. Wenn Sie Fragen haben, überlassen Sie bitte eine Nachricht, um zu diskutieren.