En primer lugar, la comunicación de iframe se divide en: comunicación del mismo dominio y comunicación de dominio cruzado.
1. Comunicación en el mismo dominio
La llamada comunicación del mismo dominio se refiere al iframe anidado de la página A.HTML en http: //localhost/demo/iframe/iframea.html
Por ejemplo: <iframe src = "http: //localhost/demo/iframe/iframeB.html" id = "iframea" name = "iframea"> Los datos de estas dos páginas se comunican. Por ejemplo, quiero llamar a la función en la página del niño en la página principal A.HTML, que es fácil para nosotros pensar en document.getElementById('iframeA').contentWindow.b(); En Google, donde B es una función en la página infantil B.HTML. Pero hay un problema con esta llamada con la que he estado luchando durante mucho tiempo, es decir, ya que he informado tal error bajo Firefox, como sigue:
B no es una función, pero claramente definí tal función en la subpágina, entonces, ¿por qué ocurre tal error? Después de un análisis cuidadoso y Google, descubrí que hay un problema que debe entenderse. Cuando el iframe no se haya cargado, ejecutaré este JS e informaré tal error. Así que intenté usar la función iframe.onload en Firefox para probarlo. Efectivamente, no había error, era correcto, así que estaba seguro de que era este problema. ¡Así que quiero escribir un IE y Firefox Google compatibles para escribir una función para confirmar que el iframe se ha cargado! , de hecho, dar una función de devolución de llamada para llamar a nuestro método anterior.
Según las ideas anteriores, puede escribir un código como este:
<iframe src = "http: //localhost/demo/iframe/iframeB.html" id = "iframea" name = "iframea"> </iframe> <div id = "topname"> topndddddddddddddddddddddddddddddddddddddddddddddd </div> <script> function a () {alerta ("a"); } var iframe = document.getElementById ('iframea'); iframeIsload (iframe, function () {var obj = document.getElementById ('iframea'). contentwindow; obj.b ();}); function iframeIsload (iframe, llamado) {if (iframe.attachevent) {iframe.attachevent ('onload', function () {callback && callback ();}); } else {iFrame.Onload = function () {callback && callback (); }}}} </script>El código B.HTML es el siguiente:
var b = function () {alert ("b"); } Es muy simple llamar a la función de la página principal en la página del niño. Solo haz esto y estará bien, window.parent.A();
La página del niño toma el valor del elemento de la página principal: window.parent.document.getElementById("topName").innerHTML y otros métodos.
Dos: comunicación de dominio cruzado de iframe.
El acceso a los derechos de dominio de Iframe generalmente se divide en dos situaciones. El primero es el dominio cruzado con el mismo dominio principal y diferentes subdominios. El segundo tipo es: diferentes dominios principales de dominios cruzados.
1. Es un dominio cruzado entre diferentes subdominios bajo el mismo dominio principal; Se puede resolver estableciendo el mismo dominio principal a través de document.domain.
Si tengo un dominio abc.example.com, hay una página llamada abc.html, y un iframe se anidada en la página de la siguiente manera: <iframe src = "http://def.example.com/demo/def.html" id = "iframe2" style = "visual ABC.HTML, todos sabemos que debido a las limitaciones de la política del mismo origen del navegador de seguridad, JS no puede operar páginas con diferentes puertos bajo diferentes protocolos bajo diferentes dominios, por lo que se resuelve el acceso al dominio cruzado. Si la página principal abc.html tiene una función js: function test(){console.log(1);}; Quiero llamar a esta función en la subpage o llamar parent.test(); De esta manera, al mirar el dominio cruzado bajo Firefox, la solución es agregar una oración document.domain = 'example.com' en la parte superior de cada función JS, y se puede resolver.
El código ABC.HTML es el siguiente:
<iframe src = "http://def.example.com/demo/def.html" id = "iframe2" style = "display: none;"> </iframe> // la función que llama a la página principal a través de subpagas de dominio (suponiendo que es la función de test a continuación) document.domain = 'Ejemplo.com.com test () {Console.log (1);El código def.html es el siguiente:
/** El método de la página infantil que llama a la página principal*/document.domain = 'ejemplo.com'; // window.top.test (); window.parent.test ();
O estas dos páginas, quiero que la página principal llame a la página del niño de la siguiente manera:
El código A.HTML es el siguiente:
/** Funciones que desean llamar a las páginas infantiles a través de la página principal del dominio*/document.domain = 'ejemplo.com'; var iframe = document.getElementById ('iframe2'); iframeIsload (iframe, function () {var obj = iframe.contentwindow; obj.child ();}); function ifRameisLoad (iframe, callback) {) if (iframe.attachevent) {iframe.attachevent ('onload', function () {callback && callback ();}); } else {iFrame.Onload = function () {callback && callback (); }}}}Si hay un código de función infantil en la página DEF.HTML ahora:
document.domain = 'ejemplo.com'; function child () {console.log ('soy una página infantil');}Puede llamar a través de los dominios, ya sea una página infantil que llama a la página principal o una página principal que llama a la página del niño. ¡Todo está bien!
2. Son diferentes dominios principales y dominios cruzados;
Aunque Google tiene varios métodos para problemas de dominio cruzado en diferentes dominios principales, incluido el método location.hash Hash, window.name Method, HTML5 y Flash, etc., creo que vale la pena aprender el siguiente método iframe.
Como se muestra en la figura a continuación: la página request.html del dominio A.com (es decir, http://a.com/demo/ajax/ajaxproxy/request.html) está anidada con un iFRame apuntando a Domain B.com (http://b.com/demo/ajaxproxy/rosponse.htmly, y el proxy.htmy.htmy.htmy.htmy.htmy.htmy.htmy.htmy.htmy.htmy.htmy.htmy.htmy.htmy.htmy.htmy.htmy.htmyht.htmyht.htmyht.htmyht.tmy.htmyht.tmyht.tmyht.tmyht.tmy A.com está anidado con el proxy.html del dominio A.com.
IDEA: Para implementar la página Soly.html bajo el proceso de solicitud de dominio A.com.php en el dominio b.com, puede pasar el parámetro de solicitud a la respuesta.html a través de la url, e iniciar una solicitud de AJAX real de la respuesta de respuesta.html a process.php (respuesta.html y process.php pertenece al dominio b.com), y luego pasar el resultado devuelto al resultado a proxy.html. Finalmente, dado que proxy.html y request.html están en el mismo dominio, puede usar Window.top para devolver el resultado en request.html para completar el dominio cruzado real.
Ok, echemos un vistazo a la estructura de la página primero
Bajo el dominio A.com, hay:
request.html
proxy.html
Bajo el dominio B.Com, hay:
respuesta.html
proceso.php
Echemos un vistazo a la página de request.html de la siguiente manera:
<! Doctype html> <html> <fead> <title> nuevo documento </title> </head> <body> <p id = "resultado"> El resultado de la respuesta se completará aquí </p> <a id = "sendBtn" href = "javaScript: void (0)"> Haga clic para enviar una solicitud de dominio cruzado </a> <ifRame Id = "Servidor" "Servidor" "" Servidor "" " style = "Display: None"> </frame> <script> document.getElementById ('sendBtn'). onClick = function () {var url = 'http://b.com/demo/ajax/AJAXPROXY/Reponse.html', fn = 'getperson', // esto es el método definido en la respuesta. 24} ', // Este es la devolución de llamada del parámetro solicitado = "devolución de llamada"; // Esta es la función de devolución de llamada ejecutada después de que se complete todo el proceso de solicitud, ejecutando la última acción CrossRequest (URL, FN, REQDATA, Callback); // Enviar una solicitud} Función CrossRequest (URL, FN, ReqData, Callback) {var server = document.getElementById ('serverif'); server.src = url + '? fn =' + encodeuricomponent (fn) + "& data =" + encodeuricomponent (reqData) + "& callback =" + encodeuricomponent (devolución de llamada); } // Función de devolución de devolución de devolución de devolución de llamada (datos) {var str = "Mi nombre es" + data.name + ". Soy un" + data.sex + ". Soy" + data.age + "años de edad"; document.getElementById ("resultado"). innerhtml = str; } </script> </body> </html> Esta página realmente trata sobre decir respuesta.html: Quiero que ejecute el método que definió GetPerson y usa el parámetro '{"id": 24}' que le di. Response.html es puramente responsable de pasar la CallBack del nombre del método al próximo hermano proxy.html. proxy.html puede ejecutarlo después de obtener la CallBack del nombre del método, porque proxy.html y request.html están en el mismo dominio.
El código Response.html es el siguiente:
<! DocType html> <html> <fead> <title> nuevo documento </title> </head> <body> <iframe id = "proxy"> </ iframe> <script> // Método general Función de solicitud de Ajax _request (reqData, url, devolución de llamada) {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; devolución de llamada (datos); }} xmlhttp.open ('post', url); xmlhttp.setRequestHeader ("Content-type", "Application/JSson; Charset = UTF-8"); xmlhttp.send (reqData); } // Método general para obtener la función de los parámetros de URL _getQuery (key) {var Query = ubicación.href.split ('?') [1], valor = decodeuricomponent (query.split (key + "=") [1] .split ("&") [0]); valor de retorno; } // Enviar solicitud AJAX a process.php Function getPerson (reqData, callback) {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=" + encodeuricomponent (data) + "& callback =" + encodeuriCoponent (callback); }; _Request (reqData, url, fn); } (function () {var fn = _getQuery ('fn'), reqData = _getQuery ("data"), callback = _getQuery ("callback"); eval (fn + "('" + reqdata + "', '" + llamado + "')");});); </script> </body> </html>Esto es en realidad para recibir la solicitud de Soly.html y obtener los parámetros y métodos de solicitud, y luego emitir una solicitud AJAX real al servidor Process.php, y luego pasar los datos devueltos del servidor y el nombre de la función de devolución de llamada pasó de request.html a proxy.html.
A continuación, echemos un vistazo al código PHP de la siguiente manera , que en realidad es solo para devolver los datos JSON:
<? Php $ data = json_decode (file_get_contents ("php: // input")); encabezado ("Content-type: Application/JSON; Charset = UTF-8"); echo ('{"id":'. $ data-> id. ', "edad": 24, "sexo": "niño", "nombre": "huangxueming"}');Finalmente, está el código proxy.html:
<! Doctype html> <html> <fead> <title> nuevo documento </title> </head> <body> <script> function _geturl (key) {// método general, obtener parámetros de url var consultación = ubicación "=") [1] .split ("&") [0]); valor de retorno; } (function () {var callback = _getUrl ("llamado"), data = _getUrl ("data"); eval ("window.top." + decodeUriCoMponent (callback) + "(" + decodeuricOponent (data) + ")");}) (); </script> </body> </html>Este es también el último paso. Proxy finalmente obtuvo el nombre de la función de devolución de llamada transmitido desde request.html a través de respuesta.html y los datos de respuesta transmitidos directamente desde respuesta.html, y usado window.top para ejecutar la función de devolución de llamada definida en request.html.
3. El problema de la alta adaptabilidad de los iframes.
La adaptación de la altura de Iframe se divide en dos tipos: uno es la adaptación bajo el mismo dominio y el otro es la adaptación bajo el dominio cruzado . Echemos un vistazo al problema de la alta adaptación en el mismo dominio.
1. Problemas con iframes altamente adaptables en el mismo dominio:
Idea: Obtenga el elemento iframe anidado, obtenga la altura final de la página anidada a través de JavaScript y luego configúrelo en la página principal para lograrlo.
Si nuestra demostración tiene iframe1.html y iframe2.html
El siguiente es el siguiente código:
<! Doctype html> <html> <fead> <title> nuevo documento </title> <style> *{margin: 0; padding: 0;} </style> </head> <body> <iframe src = "http://a.com/demo/AJAX/iframeHeight/iframe2.htmll" frameborder = "0" 0 " id = "iframe"> </iframe> <script> window.onload = function () {var iframeId = document.getElementById ('iframe'); if (iframeID &&! Window.opera) {if (iframeID.contentDocument && iframeID.contentDocument.Body.OffSetheight) {iframeId.height = iframeId.contentDocument.Body.offsEtheight; } else if (iframeid.document && iframeid.document.body.scrollheight) {iframeid.height = iframeid.document.body.scrollheight; }}} </script> </body> </html>iframe2.html
<! Doctype html> <html> <fead> <title> nuevo documento </title> <style> *{margin: 0; relleno: 0;} </style> </head> <body> <div style = "altura: 500px;"> </div> </body> </html>Puede establecer dinámicamente la altura de la página iframe1 en la altura de iframe2.
2. Los iframes son altamente adaptables en todos los dominios.
En primer lugar, sabemos que no podemos controlar el dominio cruzado de iframes con el método JS anterior, por lo que solo podemos usar la clave intermedia para anidar una página iframe2.html en el dominio b.com en la página iframe1.html en el dominio a.com, y luego anido una página iframe3.html con el mismo dominio que iframe1.htmll en la página iframe2.html. De esta manera, iframe1.html y iframe3.html puede comunicarse sin barreras, porque la página iframe2.html nida iframe3.html, por lo que iframe2.html puede reescribir el valor href de iframe3.html.
Contenido en iframe1:
El contenido IFRAME1.HTML acepta principalmente el contenido transmitido desde la página iframe3.html y completa la operación correspondiente. El código iframe1.html es el siguiente:
<iframe src = "http://b.com/demo/ajax/iframeheight/iframe2.html" id = "iframe"> </iframe> <script> var ifr_el = document.getElementById ("iframe"); función getifrData (data) {ifr_el.style.height = data+"px"; } </script>Contenido en iframe2.html:
¿Cómo pasa el contenido Iframe2.html el valor a la página Iframe3.html? Acabo de decir que el valor se pasa al href de la página iframe3.html, así que simplemente modifique el SRC del iframe. Debido a que no es necesario actualizar la página C, hash se puede pasar a la página iframe3.html por hash. El código de iframe2.html es el siguiente:
<! Doctype html> <html> <fead> <title> nuevo documento </title> <style> *{margin: 0; padding: 0;} </style> </head> <body> <iframe id = "iframe" src = "http://a.com/dema/ajax/iframeheight/iframe3.htmlame> </if if if ifi var OldHeight = 0, ifr_el = document.getElementById ("iframe"); T && ClearInterval (t); var t = setInterval (function () {var Height = document.body.scrollheight; if (OldHeight! = Height) {Oldheight = Height; ifr_el.src += '#' +oldheight;}}, 200); </script> </body> </html>Puede ver que de forma predeterminada, la altura de la página iframe1.html doy iframe2.html es 200 píxeles, pero en iframe2.html doy iframe3.html la altura del iframe3.html es 230 píxeles, por lo que en circunstancias normales hay una barra desplazada. Ahora quiero obtener la altura de la barra de desplazamiento en iframe2.html, pasar la altura al src a través de iframe3.html, y luego obtener el valor de altura en la página iframe3.html para pasarlo a iFrame1.html (porque iframe1.html y iframe3.html están en el mismo dominio), por lo tanto. altura en sí, está bien.
La única función de la página iframe3.html es recibir el valor aprobado por la página Iframe2.html a través del href y pasarlo a la página iframe1.html. El valor pasado a la página iframe2.html se puede verificar continuamente a través de un temporizador para ver si la ubicación. Otra forma es escuchar los cambios de HREF a través onhashchange (IE8+, Chrome5.0+, Firefox3.6+, Safari5.0+, Opera10.6+) en el nuevo navegador.
El código iframe3.html es el siguiente:
<script> var OldHeight = 0; T && ClearInterval (t); var t = setInterval (function () {var Height = Ubuse.href.split ('#') [1]; if (Height && Height! = OldHeight) {OldHeight = Height; if (Window.Parent.Parent.getifrData) {Window.Parent.Parent.getifrdata (OldHeight);}}}}, 200); </script>Esto puede resolver el problema de lograr la altura de la adaptabilidad para iframe a través del dominio cruzado.
4. Resumen
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el estudio y el trabajo de todos. Si tiene alguna pregunta, deje un mensaje para discutir.