Прежде всего, общение IFRAME делится на: общение с той же доменом и междоменную связь.
1. Коммуникация в том же домене
Так называемая связь с той же доменом относится к вложенной Iframe на странице A.HTML под http: //localhost/demo/iframe/iframea.html
Например: <iframe src = "http: //localhost/demo/iframe/iframeb.html" id = "iframea" name = "iframea"> Данные этих двух страниц общаются. Например, я хочу вызвать функцию на детской странице на родительской странице A.HTML, которая для нас легко подумать о document.getElementById('iframeA').contentWindow.b(); Под Google, где B является функцией на детской странице B.html. Но есть проблема с этим вызовом, с которой я долго боролся, то есть, поскольку я сообщил о такой ошибке при Firefox, следующим образом:
B не является функцией, но я четко определил такую функцию на подпанице, так почему же возникает такая ошибка? После тщательного анализа и Google я обнаружил, что есть проблема, которую необходимо понять. Когда iframe не загружен, я выполню этот JS и сообщу о такой ошибке. Поэтому я попытался использовать функцию iframe.onload под Firefox, чтобы проверить ее. Конечно же, ошибки не было, это было правильно, поэтому я был уверен, что это была эта проблема. Поэтому я хочу написать совместимый IE и Firefox Google, чтобы написать функцию, чтобы подтвердить, что iframe был загружен! На самом деле, дайте функцию обратного вызова, чтобы вызвать наш метод выше.
Основываясь на приведенных выше идеях, вы можете написать код, как это:
<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 ();}); функция iframeisload (iframe, callback) {if (iframe.attachevent) {iframe.attachevent ('Onload', function () {callback && callback ();}); } else {iframe.onload = function () {callback && callback (); }}}} </script>Код B.HTML выглядит следующим образом:
var b = function () {alert ("b"); } Очень просто вызвать функцию родительской страницы на детской странице. Просто сделай это, и все будет в порядке, window.parent.A();
Страница дочерности принимает значение элемента родительской страницы: window.parent.document.getElementById("topName").innerHTML и другие методы.
Два: перекрестная связь Iframe.
Доступ к перекрестному домену iframe обычно делится на две ситуации. Первый-это междомен с одним и тем же основным доменом и разными поддоменами. Второй тип: разные основные домены поперечных доменов.
1. Это перекрестный домен между различными субдоменами под одной и той же основной доменом; Это может быть решено путем установки того же основного домена через Document.domain.
Если у меня есть домен abc.example.com, на странице есть страница, называемая abc.html, а iframe вложена на страницу следующим образом: <iframe src = "http://def.example.com/demo/def.html" id = "iframe2" style = "none;> </iframe>, я хочу получить доступ к Def.h. in def. Abc.html Мы все знаем, что из-за ограничений одинаковой политики в отношении браузера безопасности JS не может работать с разными портами в разных протоколах под разными областями, поэтому доступ к междомену решается. Если родительская страница abc.html имеет функцию JS: function test(){console.log(1);}; Я хочу вызвать эту функцию на подпаке или вызов parent.test(); Таким образом, глядя на перекрестный домен под Firefox, решение состоит в том, чтобы добавить предложение document.domain = 'example.com' в верхней части каждой функции JS, и его можно решить.
Код ABC.HTML выглядит следующим образом:
<iframe src = "http://def.example.com/demo/def.html" id = "iframe2" style = "display: none;"> </iframe> // функция, которая вызывает родительскую страницу по доменным подпажам (предполагая, это функция теста ниже) document.domain = 'example.com';
Код DEF.HTML выглядит следующим образом:
/** Метод детской страницы, вызывающая родительскую страницу*/document.domain = 'example.com'; // window.top.test (); window.parent.test ();
Или эти две страницы, я хочу, чтобы родительская страница позвонила на странице ребенка следующим образом:
A.HTML -код выглядит следующим образом:
/** Функции, которые хотят вызывать дочерние страницы по всей странице родительской страницы домена*/document.domain = 'example.com'; var iframe = document.getelementbyid ('iframe2'); iframeisload (iframe, function () {var obj = iframe.contentwindow; obj.child ();}); iframelad (iframe, callback) if (iframe.attachevent) {iframe.attachevent ('Onload', function () {callback && callback ();}); } else {iframe.onload = function () {callback && callback (); }}}}Если на странице DEF.HTML есть код функции дочерней функции:
document.domain = 'example.com'; function child () {console.log ('i re are are page');}Вы можете позвонить по доменам, будь то дочерняя страница, которая звонит на родительскую страницу или родительскую страницу, вызывающую ребенка. Все в порядке!
2. Это разные основные домены и поперечные домены;
Хотя у Google есть несколько методов для проблем с междоменом в разных основных доменах, включая метод location.hash , метод window.name , HTML5 и Flash и т. Д., Я думаю, что следующий метод IFRAME стоит изучить.
Как показано на рисунке ниже: Page request.html of Domain A.com (т.е. http://a.com/demo/ajax/ajaxproxy/request.html) вложено с указанием iframe/response.h.homl.h.homly.h.homl. A.com вложен в прокси. Html Domain A.com.
Идея: Чтобы реализовать страницу request.html в соответствии с процессом запроса домена A.com в рамках домена B.com, вы можете передать параметр запроса в ответ .html через URL и инициировать реальный запрос Ajax из response.html в процесс. Наконец, поскольку proxy.html и request.html находятся в том же домене, вы можете использовать window.top, чтобы вернуть результат в request.html для завершения реального перекрестного домена.
Хорошо, сначала посмотрим на структуру страницы
Под доменом A.com есть:
request.html
Proxy.html
Под доменом B.com есть:
response.html
Process.php
Давайте посмотрим на страницу запроса. HTML следующим образом:
<! Doctype html> <html> <head> <title> новый документ </title> </head> <body> <p id = "result"> Результат ответа будет заполнен здесь </p> <a id = "sendbtn" href = "javaScript: void (0)"> Нажмите, чтобы отправить запрос перекрестного домана </a> <idrame id " style = "Display: none"> </iframe> <script> document.getElementById ('sendbtn'). onclick = function () {var url = 'http://b.com/demo/ajax/ajaxproxy/reponse.html', fn = 'getPerson', // это метод defined in response.html ', fn =' getPerson ', // это метод defined in in response.htm : 24} ', // Это запрошенный параметр callback = "обратный вызов"; // Это функция обратного вызова, выполненную после завершения всего процесса запроса, выполнив последнее действие CrossRequest (URL, FN, REQData, Callback); // Отправить запрос} функция CrossRequest (url, fn, reqdata, callback) {var server = document.getElementbyid ('serverif'); server.src = url + '? fn =' + encodeuricomponent (fn) + "& data =" + encodeuricomponent (reqdata) + "& callback =" + encodeuricomponent (обратный вызов); } // Функция обратного обращения Callback (data) {var str = "Мое имя" + data.name + ". Я -" + data.sex + ". I Am Am" + Data.age + "лет."; document.getElementbyId ("result"). innerHtml = str; } </script> </body> </html> Эта страница на самом деле о том, чтобы сообщить response.html: Я хочу, чтобы вы выполнили метод, который вы определили GetPerson , и использовать параметр '{"id": 24}' Я вам дал. response.html несет исключительную ответственность за передачу CallBack имени метода следующему брату proxy.html. Proxy.html может выполнить его после получения CallBack имени метода, потому что Proxy.html и request.html находятся в одном домене.
Код response.html выглядит следующим образом:
<! Doctype html> <html> <head> <title> Новый документ </title> </head> <body> <iframe id = "proxy"> </iframe> <script> // Общий метод ajax function _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; обратный вызов (данные); }} xmlhttp.open ('post', url); xmlhttp.setrequestheader ("Content-type", "Application/json; charset = utf-8"); xmlhttp.send (reqdata); } // Общий метод для получения функции параметров URL _getQuery (key) {var Query = location.href.split ('? возвращаемое значение; } // Отправить запрос ajax на функцию process.php 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 =" + encodeuricomponent (обратный вызов); }; _request (reqdata, url, fn); } (function () {var fn = _getQuery ('fn'), reqData = _getQuery ("data"), callback = _getQuery ("обратный вызов"); eval (fn + "(" + reqdata + "','" + обратный вызов + "')");}) ();); </script> </body> </html>Это на самом деле для получения запроса от request.html и получения параметров и методов запроса, а затем выдать реальный запрос Ajax на Server Process.php, а затем передайте данные, возвращаемые с сервера, и имя функции обратного вызова, передаваемое из request.html в proxy.html.
Далее, давайте посмотрим на код PHP следующим образом , что на самом деле просто для возврата данных JSON:
<? php $ data = json_decode (file_get_contents ("php: // input")); Header ("Content-Type: Application/json; charset = utf-8"); echo ('{"id":'. $ data-> id.Наконец, есть код proxy.html:
<! Doctype html> <html> <head> <title> Новый документ </title> </head> <body> <script> function _geturl (Key) {// Общий метод, получить параметры url var Query = location.href.split ("?") "=") [1] .split ("&") [0]); возвращаемое значение; } (function () {var callback = _geturl ("callback"), data = _geturl ("data"); eval ("window.top." + decodeuricomponent (callback) + "(" + decodeuricomponent (data) + ")");}) (); </script> </body> </html>Это также последний шаг. Прокси, наконец, получил имя функции обратного вызова, передаваемое из recemed.html через response.html и данные ответа, передаваемые непосредственно из response.html, и используемого window.top для выполнения функции обратного вызова, определенной в reffer.html.
3. Проблема высокой адаптивности iframes.
Адаптация высоты IFRAME разделена на два типа: один - адаптация под одной и той же доменом, а другой - адаптация под поперечным доменом . Давайте посмотрим на проблему высокой адаптации в той же области.
1. Проблемы с высокоадальными iframes в одной и той же домене:
Идея: Получите вложенный элемент iframe, получите окончательную высоту вложенной страницы через JavaScript, а затем установите его на главной странице для достижения ее.
Если у нашей демонстрации есть iframe1.html и iframe2.html
Ниже приведен следующий код:
<! Doctype html> <html> <head> <title> Новый документ </title> <style> *{margin: 0; Padding: 0;} </style> </head> <body> <iframe src = "http://a.com/demo/ajax/iframeheight/iframe2.html". 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> <head> <title> Новый документ </title> <style> *{margin: 0; Padding: 0;} </style> </head> <body> <div style = "height: 500px;"> </div> </body> </html>Вы можете динамически установить высоту страницы iframe1 на высоту iframe2.
2. iframes очень адаптируемым между доменами.
Во-первых, мы знаем, что мы не можем контролировать перекрестную домен IfRames с помощью приведенного выше метода JS, поэтому мы можем использовать только промежуточный ключ, чтобы гнездовать страницу iframe2.html под доменом b.com на странице iframe1.html под доменом a.com, а затем я вложен на странице iframe3.html с тем же доменом, что и Iframe1.html. Таким образом, iframe1.html и iframe3.html могут общаться без барьеров, потому что страница iframe2.html гнезд iframe3.html, поэтому iframe2.html может переписать значение href iframe3.html.
Содержание в iframe1:
Содержание iframe1.html в основном принимает контент, передаваемый со страницы iframe3.html, и завершает соответствующую операцию. Код iframe1.html выглядит следующим образом:
<iframe src = "http://b.com/demo/ajax/iframeheight/iframe2.html" id = "iframe"> </iframe> <script> var ifr_el = document.getElementById ("iframe"); function getifrdata (data) {ifr_el.style.height = data+"px"; } </script>Контент в iframe2.html:
Как контент iframe2.html передает значение странице iframe3.html? Я только что сказал, что значение передается в HREF страницы IFRAME3.HTML, поэтому просто измените SRC IFRAME. Поскольку нет необходимости обновлять страницу C, она может быть передана на страницу iframe3.html от хэша. Код iframe2.html выглядит следующим образом:
<! Doctype html> <html> <head> <title> Новый документ </title> <style> *{margin: 0; Padding: 0;} </style> </head> <body> <iframe id = "iframe" src = "http://a.com/demo/ajax/iframe" src = "/iframe3 <Script> 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>Вы можете видеть, что по умолчанию высота iframe1.html I даю iframe2.html 200 пикселей, но в iframe2.html я даю iframe3.html высоту iframe3.html 230 пикселей, поэтому при нормальных обстоятельствах есть шар. Теперь я хочу получить высоту полосы прокрутки в iframe2.html, перенесите высоту на странице src через iframe3.html, а затем получите значение высоты на странице iframe3.html, чтобы перенести его в iframe1.html (потому что iframe1.html и iframe3.html. Сама высота, все в порядке.
Единственная функция страницы iframe3.html - получить значение, передаваемое страницей iframe2.html через HREF, и передать его на страницу iframe1.html. Значение, передаваемое на странице iframe2.html, можно непрерывно проверять через таймер, чтобы увидеть, было ли изменено место. Href, но это кажется очень неэффективным. Другим способом является прослушивание изменений HREF через событие onhashchange (IE8+, Chrome5.0+, Firefox3.6+, Safari5.0+, Opera10.6+) в новом браузере.
Код iframe3.html выглядит следующим образом:
<script> var oldheight = 0; t && clearInterval (t); var t = setInterval (function () {var height = location.href.split ('#') [1]; if (height && height! = OldHeight) {OldHeight = height; if (window.parent.parent.getifrdata) {window.parent.parent.getifrdata (oldheight); </script>Это может решить проблему достижения высоты адаптивности IFRAME через междомен.
4. Резюме
Вышеуказанное - все содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения и работы. Если у вас есть какие -либо вопросы, пожалуйста, оставьте сообщение для обсуждения.