まず、IFRAME通信は、同じドメイン通信とクロスドメイン通信に分かれています。
1。同じドメイン内の通信
いわゆる同じドメイン通信は、http://localhost/demo/iframe/iframea.htmlに基づくa.htmlページのネストされたiframeを指します
たとえば、<iframe src = "http://localhost/demo/iframe/iframeb.html" id = "iframea" name = "iframea">これらの2ページのデータは通信します。たとえば、親ページA.htmlの子ページの関数を呼び出したいと思います。これはdocument.getElementById('iframeA').contentWindow.b(); Googleの下では、Bは子供ページB.htmlの関数です。しかし、この呼び出しには、私が長い間苦労してきたという問題があります。つまり、Firefoxの下でそのようなエラーを報告したので、次のようになります。
bは関数ではありませんが、サブページでそのような関数を明確に定義したのに、なぜそのようなエラーが発生するのですか?慎重な分析とGoogleの後、理解する必要がある問題があることがわかりました。 IFRAMEがロードされていない場合、このJSを実行して、そのようなエラーを報告します。そこで、Firefoxの下のiframe.onload関数を使用してテストしようとしました。案の定、エラーはありませんでした、それは正しかったので、私はそれがこの問題であると確信しました。だから私は互換性のある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およびその他のメソッド。
2:IFRAMEクロスドメイン通信。
IFRAMEクロスドメインアクセスは、通常、2つの状況に分かれています。 1つ目は、同じメインドメインと異なるサブドメインを備えたクロスドメインです。 2番目のタイプは次のとおりです。異なるメインドメインクロスドメイン。
1.同じメインドメインの下で異なるサブドメイン間のクロスドメインです。 Document.domainを使用して同じメインドメインを設定することで解決できます。
ドメインabc.example.comがある場合、abc.htmlというページがあり、iframeは次のようにページにネストされています。 Page ABC.htmlセキュリティブラウザーの同じオリジンポリシーの制限により、JSは異なるドメインの下で異なるプロトコルの下で異なるポートを持つページを操作できないため、クロスドメインアクセスが解決されます。親ページABC.htmlにjs関数がある場合: function test(){console.log(1);}; parent.test();このようにして、Firefoxの下のクロスドメインを見ることにより、解決策は、各JS関数の上部にdocument.domain = 'example.com'を作成することです。
ABC.htmlコードは次のとおりです。
<iframe src = "http://def.example.com/demo/def.html" id = "iframe2" style = "display:none;"> </iframe> //ドメインサブページを越えて親ページを呼び出す関数(テスト機能であると仮定)document.domain = 'Domen "
def.htmlコードは次のとおりです。
/**親ページを呼び出す子ページのメソッドwindow.parent.test();
または、これらの2ページで、親ページに次のように子ページを呼び出してもらいたいです。
A.HTMLコードは次のとおりです。
/**ドメインの親のページを介して子どものページを呼び出したいページ*/document.domain = 'emple.com'; var iframe = document.getElementbyid( 'iframe2'); iframeisload(var obj = iframe.contentwindow; obj.child();}); if(iframe.attachevent){iframe.attachevent( 'onload'、function(){callback && callback();}); } else {iframe.onload = function(){callback && callback(); }}}}今すぐdef.htmlページに子関数コードがある場合:
document.domain = 'emple.com'; function child(){console.log( '私は子のページ');}親ページを呼び出す子ページであろうと、子ページを呼び出す親ページであろうと、ドメイン全体で呼び出すことができます。すべてが大丈夫です!
2。それは異なる主要なドメインとクロスドメインです。
Googleには、 location.hashメソッド、 window.nameメソッド、html5、フラッシュなどを含むさまざまなメインドメインに関するクロスドメインの問題のいくつかの方法がありますが、次のiframeメソッドは学習する価値があると思います。
以下の図に示すように:ドメインA.comのページrequest.html(つまりhttp://a.com/demo/ajax/ajaxproxy/request.html)は、ドメインB.com(http://b.com/demo/ajaxproxy/resposonsuls.htmlを指すiframeがネストされています。ドメインA.comは、ドメインA.comのproxy.htmlでネストされています。
アイデア:a.comドメインrequest process.phpでrequest.htmlページをドメインb.comでリクエストパラメーターをresponse.htmlに渡すことができ、response.htmlからprocess.php(response.htmlおよびprocess.phpがドメインb.comに属します)を実行できます。最後に、proxy.htmlとrequest.htmlは同じドメインにあるため、window.topを使用してrequest.htmlの結果を返すために実際のクロスドメインを完了することができます。
わかりました、最初にページ構造を見てみましょう
A.Comドメインの下には、次のようなものがあります。
request.html
proxy.html
B.comドメインの下には、次のことがあります。
Response.html
process.php
次のように、request.htmlページを見てみましょう。
<!Doctype html> <html> <head> <title> new Document>新しいドキュメント</title> </head> <body> <p id = "result">応答結果はここに記入されます</p> <a id = "sendbtn" href = "javascript:void(0)" <script> document.getElementById( 'sendbtn')。onclick = function(){var url = 'http://b.com/demo/ajax/ajaxproxy/reponse.html'、fn = 'getperson'、//これは応答で定義された方法です。パラメーターコールバック= "callback"; //これは、要求プロセス全体が完了した後に実行されるコールバック関数であり、最後のアクションCrossRequest(URL、FN、ReqData、CallBack)を実行します。 //リクエストを送信} function 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.sex + "です。 document.getElementById( "result")。innerhtml = str; } </script> </body> </html>このページは、実際にResponse.htmlを伝えることに関するものです。HTML: GetPersonを定義したメソッドを実行し、パラメーター '{"id":24}'を使用してください。 Response.htmlは、次のBrother Proxy.htmlにメソッド名のCallBackを渡すことに純粋に責任があります。 proxy.htmlとrequest.htmlが同じドメインにあるため、メソッド名のCallBackを取得した後にproxy.htmlが実行できます。
Response.htmlコードは次のとおりです。
<!doctype html> <html> <head> <title> new Document> new Document> </title> </head> <body> <body> <iframe id = "proxy"> </iframe> <script> //一般的な方法ajax要求関数_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; callback(data); }} xmlhttp.open( 'post'、url); xmlhttp.setRequestheader( "content-type"、 "application/json; charset = utf-8"); xmlhttp.send(reqdata); } // URLパラメーター機能を取得する一般的な方法_getQuery(key){var query = location.href.split( '?')[1]、value = decodeuricomponent(query.split(key + "=")[1] .split( "&")[0]);返品値。 } // process.php function getPerson(reqdata、callback)にajax requestを送信する{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 + "&callback =" + encodeuricomponent(callback); }; _Request(reqdata、url、fn); }(function(){var fn = _getquery( 'fn')、reqdata = _getquery( "data")、callback = _getquery( "callback"); eval(fn + "( '" + reqdata + "'、 '" + callback + "');}); </script> </body> </html>これは、実際にrequest.htmlからリクエストを受信してリクエストパラメーターとメソッドを取得し、サーバーprocess.phpに実際のajax requestを発行し、サーバーから返されるデータを渡し、request.htmlからproxy.htmlに渡されたコールバック関数名を渡すことです。
次に、次のようにPHPコードを見てみましょう。これは、実際にはJSONデータを返すためだけです。
<?php $ data = json_decode(file_get_contents( "php:// input"));ヘッダー( "Content-Type:Application/JSON; charset = utf-8"); echo( '{"id":'。$ data-> id。 '、 "age":24、 "sex": "boy"、 "name": "huangxueming"}');?>最後に、proxy.htmlコードがあります。
<!doctype html> <html> <head> <title> new Document> new Document> new Document </title> </head> <body> <script> function _geturl(key){//一般的な方法、urlパラメーターvar query = location.href.split( "?")[1]、value = decodeuricponent(query.split "=")[1] .split( "&")[0]);返品値。 }(function(){var callback = _geturl( "callback")、data = _geturl( "data"); eval( "window.top。" + decodeuricomponent(callback) + "(" + decodeuricomponent(data) + ");})(})(); </script> </body> </html>これも最後のステップです。 Proxyは最終的に、Response.htmlとResponse.htmlから直接送信されたReponse.htmlからrequest.htmlから送信され、windop.topを使用してrequest.htmlで定義されたコールバック関数を実行しました。
3。IFRAMEの高い適応性の問題。
IFRAME高さの適応は2つのタイプに分けられます。1つは同じドメインの下での適応であり、もう1つはクロスドメインの下での適応です。同じドメインでの高い適応の問題を見てみましょう。
1。同じドメイン内の高度に適応性のあるIFRAMEの問題:
アイデア:ネストされたiframe要素を取得し、JavaScriptを使用してネストされたページの最終的な高さを取得し、メインページに設定してそれを実現します。
デモにiframe1.htmlとiframe2.htmlがある場合
以下は次のコードです。
<!Doctype html> <html> <head> <title> new Document> new Document>新しいドキュメント</title> <style> *{margin:0; padding:0;} </style> </head> <body> <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.offseetheight){iframeid.height = iframeid.contentdocument.body.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> new Document> new Document>新しいドキュメント</title> <style> *{margin:0; padding:0;} </style> </head> <body> <div style = "height:500px;"> </div> </body> </html>iframe1ページの高さをiframe2の高さに動的に設定できます。
2。IFRAMEはドメイン全体で高度に適応可能です。
まず第一に、上記のJSメソッドでIFRAMEのクロスドメインを制御できないことがわかっているため、中間キーを使用してA.Comドメインの下にあるiframe1.htmlページのB.comドメインの下にあるiframe2.htmlページをネストすることができます。このようにして、iframe2.htmlがiframe3.htmlをネストするため、iframe1.htmlと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");関数getifrdata(data){ifr_el.style.height = data+"px"; } </script>iframe2.htmlのコンテンツ:
iframe2.htmlコンテンツは、値をiframe3.htmlページにどのように渡しますか?値はiframe3.htmlページのhrefに渡されると言ったので、iframeのsrcを変更するだけです。 Cページを更新する必要はないため、Hashでiframe3.htmlページに渡すことができます。 iframe2.htmlのコードは次のとおりです。
<!Doctype html> <html> <head> <title> new Document> new Document> new Document </title> <style> *{margin:0; padding:0;} </style> </head> <body> <iframe id = "iframe" src = "http://a.com/.com/.com/ajax/iframeheighighighighighighighighighighighighighighighighighighighighighight/iframe 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 += '#' +' +' +}}、200); </script> </body> </html>デフォルトでは、iframe1.htmlページの高さはiframe2.htmlを200ピクセルにしますが、iframe2.htmlではiframe3.htmlを与えます3.htmlは230ピクセルです。次に、iframe2.htmlのスクロールバーの高さを取得し、iframe3.htmlを介して高さをSrcに渡し、iframe3.htmlページの高さ値を取得してiframe1.htmlに渡します(iframe1.htmlおよびiframe3.htmlは同じドメインであるため)などです。高さ自体、大丈夫です。
iframe3.htmlページの唯一の関数は、hrefを介してiframe2.htmlページで渡された値を受信し、それをiframe1.htmlページに渡すことです。 iframe2.htmlページに渡された値は、タイマーを介して継続的にチェックして、location.hrefが変更されたかどうかを確認できますが、これは非常に非効率的です。別の方法は、新しいブラウザでonhashchange (IE8+、Chrome5.0+、Firefox3.6+、Safari5.0+、Opera10.6+)を通じてHREFの変更を聞くことです。
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。概要
上記は、この記事のコンテンツ全体です。みんなの勉強や仕事に役立つことを願っています。ご質問がある場合は、メッセージを残して話し合ってください。