別のドメインのiframeのサイズを変更するにはどうすればよいですか
-編集
いくつかの解決策については下にスクロールしてください..またはこれを行わない方法を読んでください:D
何時間にもわたるコードハッキングの後、結論として、私のドメインでレンダリングされるスクロールバーでさえ、iframe内のすべてにアクセスできなくなりました。私は無駄に多くのテクニックを試しました。
時間を節約するために、このルートをたどらないでください。クロスドメイン通信にはsendMessagesを使用してください。 私が使用しているHTML <5のプラグインがあります-良い例については一番下に移動してください:)
過去数日間、私はiframeをサイトに統合しようとしています。これは、反対側が開発してAPIを開発している間の短期的な解決策です(数か月かかる可能性があります...)そして、これは短期的な解決策であるため、easyXDMを使用したいと思います-私は他のドメインにアクセスできますが、 p3pヘッダーをそのまま追加.....
3つのiframe
私が見つけた最も近い解決策は3つのiframeでしたが、それはクロムとサファリの精神に影響するため、それを使用することはできません。
クロームで開く
http://css-tricks.com/examples/iFrameResize/crossdomain.php#frameId=frame-one&height=1179
スクロールバーを測定する
scrollheightを使用してフォームのサイズを変更する方法に関する別の投稿を見つけました。理論的にはうまく機能しますが、iframeのスクロールの高さを使用して適切に適用できませんでした。
document.body.scrollHeight
それは明らかに体の高さを使用します(これらのプロパティに100%アクセスすることはできません100%はクライアントの表示canvazに基づいており、xドメインのドキュメントの高さではありません)
jqueryを使用してiframeの高さを取得してみました
$('#frameId').Height()
$('#frameId').clientHeight
$('#frameId').scrollHeight
クロムとは異なる戻り値、つまり-またはまったく意味がありません。問題は、フレーム内のすべてが拒否されることです-スクロールバーも...
計算されたスタイル
しかし、iframeのクロムを調べて要素を表示すると、iframe内のドキュメントの寸法が表示されます(jquery x-domainを使用してiframe.heighを取得します-アクセスが拒否されました)計算されたCSSには何もありません
さて、クロムはそれをどのように計算しますか?(edit-browserは、組み込みのレンダリングエンジンを使用してページを再レンダリングし、これらすべての設定を計算しますが、クロスドメイン詐欺を防ぐためにどこにも添付されていません。
HTML4
HTML4.xの仕様を読みましたが、document.elementを介して読み取り専用の値を公開する必要があると書かれていますが、jqueryを介してアクセスが拒否されています
プロキシフレーム
ユーザーがiframeを介してログインし、プロキシが実際のコンテンツではなくログインページを取得するまで、サイトをプロキシして、どちらが問題ないかを計算するというルートをたどりました。また、ページを2回呼び出すことは受け入れられない人もいます
http://www.codeproject.com/KB/aspnet/asproxy.aspx
http://www.johnchapman.name/aspnet-proxy-page-cross-domain-requests-from-ajax-and-javascript/
ページを再レンダリングする
ここまでは行きませんでしたが、ソースを調べてソースファイルに基づいてページを再レンダリングするjscriptエンジンがあります。しかし、それらのjscriptをハッキングする必要があります..そしてそれは営利団体にとって理想的な状況ではありません...そしていくつかは純粋なJavaアプレットまたはサーバーサイドレンダリングを含みます
http://en.wikipedia.org/wiki/Server-side_JavaScript
http://htmlunit.sourceforge.net/ <-java not jscript
2013年9月の更新を編集
これはすべて、HTML5ソケットで実行できます。しかし、easyXDMは、HTML5以外の苦情ページの優れたフォールバックです。
解決策1非常に優れた解決策!
easyXDMの使用
サーバー上で、次の形式のページを設定します。
<html>
<head>
<script src="scripts/easyXDM.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
var transport = new easyXDM.Socket(/** The configuration */{
remote: "http://www.OTHERDOMAIN.com/resize_intermediate.html?url=testpages/resized_iframe_1.html",
//ID of the element to attach the inline frame to
container: "embedded",
onMessage: function (message, origin) {
var settings = message.split(",");
//Use jquery on a masterpage.
//$('iframe').height(settings[0]);
//$('iframe').width(settings[1]);
//The normal solution without jquery if not using any complex pages (default)
this.container.getElementsByTagName("iframe")[0].style.height = settings[0];
this.container.getElementsByTagName("iframe")[0].style.width = settings[1];
}
});
</script>
</head>
<body>
<div id="embedded"></div>
</body>
発信者ドメインでは、intermiedate_framehtmlとeasyXDM.jsを同じ場所に追加するだけです。親フォルダのように-あなたはあなたのためだけに相対ディレクトリまたは含まれているフォルダにアクセスすることができます。
オプション1
すべてのページにスクリプトを追加したくない場合は、オプション2を参照してください。
次に、サイズ変更が必要な各ページの最後に簡単なjscriptを追加するだけです。これらの各ページにeasyxdmを含める必要はありません。
<script type="text/javascript">
window.onload = function(){ parent.socket.postMessage( (parseInt(document.body.clientHeight)) + "," + ( document.body.clientWidth ) ); };
</script>
送信するパラメータを変更しました。幅を適切に機能させたい場合は、otherdomainのページに、次のようなスタイルでページの幅を含める必要があります。
<style type="text/css">
html, body {
overflow: hidden;
margin: 0px;
padding: 0px;
background-color: rgb(75,0,85);
color:white;
width:660px
}
a {
color:white;
visited:white;
}
</style>
これは私にとって素晴らしい働きをします。幅が含まれていない場合、フレームは少し奇妙に動作し、「あるべきもの」を推測しようとします。必要に応じて縮小することはありません。
オプション2
変更をポーリングするように中間フレームを変更します
中間フレームは次のようになります。
<!doctype html>
<html>
<head>
<title>Frame</title>
<script type="text/javascript" src="easyXDM.js">
</script>
<script type="text/javascript">
var iframe;
var socket = new easyXDM.Socket({
//This is a fallback- not needed in many cases
swf: "easyxdm.swf",
onReady: function(){
iframe = document.createElement("iframe");
iframe.frameBorder = 0;
document.body.appendChild(iframe);
iframe.src = "THE HOST FRAME";
iframe.onchange = messageBack();
},
onMessage: function(url, origin){
iframe.src = url;
}
});
//Probe child.frame for dimensions.
function messageBack(){
socket.postMessage ( iframe.contentDocument.body.clientHeight + "," + iframe.contentDocument.body.clientWidth);
};
//Poll for changes on children every 500ms.
setInterval("messageBack()",500);
</script>
<style type="text/css">
html, body {
overflow: hidden;
margin: 0px;
padding: 0px;
width: 100%;
height: 100%;
}
iframe {
width: 100%;
height: 100%;
border: 0px;
}
</style>
</head>
<body>
</body>
</html>
サイズが変更された場合にチェックし、サイズが変更された場合にのみ送信するために、間隔をより効率的にすることができます。500ミリ秒ごとにメッセージを投稿する必要はありません。このチェックを実装すると、ポーリングを50ミリ秒まで変更できます。楽しんで
ブラウザ間で動作し、高速です。素晴らしいデバッグ機能!!
Excellent Work to Sean Kinsey who made the script!!!
解決策2(機能しますが、あまり良くありません)
したがって、基本的に、他のドメインと相互に合意している場合は、sendmessageを処理するライブラリを追加できます。他のドメインにアクセスできない場合は、さらにハックを探し続けてください。見つけたハックを見つけることができなかったか、完全に正当化できなかったためです。
したがって、他のドメインはこれらをHeadタグに含めます
<script src="scripts/jquery-1.5.2.min.js" type="text/javascript"></script>
<script src="scripts/jquery.postmessage.min.js" type="text/javascript"></script>
<script src="scripts/club.js" type="text/javascript"></script>
club.jsには、サイズ変更呼び出しのために行ったカスタム呼び出しがいくつかあり、が含まれています。
$(document).ready(function () {
var parent_url = decodeURIComponent( document.location.hash.replace( /^#/, '' ) ),link;
//Add source url hash to each url to authorise callback when navigating inside the frame.Without this clicking any links will break the communication and no messages will be received
$('a[href]').each(function(){
this.href = this.href + document.location.hash ;
});
//Get the dimensions and send back to calling page.
var h1 = document.body.scrollHeight;
var w1 = document.body.scrollWidth;
$.postMessage({ if_height: h1, if_width: w1 }, parent_url, parent );
});
そして、あなたのページはすべての大変な仕事をし、素晴らしいスクリプトを持っています...
//This is almost like request.querystring used to get the iframe data
function querySt(param, e) {
gy = e.split("&");
for (i = 0; i < gy.length; i++) {
ft = gy[i].split("=");
if (ft[0] == param) {
return ft[1];
}
}
}
$(function () {
// Keep track of the iframe dimensions.
var if_height;
var if_width;
// Pass the parent page URL into the Iframe in a meaningful way (this URL could be
// passed via query string or hard coded into the child page, it depends on your needs).
src = 'http://www.OTHERDOAMIN.co.uk/OTHERSTARTPAGE.htm' + '#' + encodeURIComponent(document.location.href),
// Append the Iframe into the DOM.
iframe = $('<iframe " src="' + src + '" width="100%" height="100%" scrolling="no" frameborder="0"><\/iframe>').appendTo('#iframe');
// Setup a callback to handle the dispatched MessageEvent event. In cases where
// window.postMessage is supported, the passed event will have .data, .origin and
// .source properties. Otherwise, this will only have the .data property.
$.receiveMessage(function (e) {
// Get the height from the passsed data.
//var h = Number(e.data.replace(/.*if_height=(\d+)(?:&|$)/, '$1'));
var h = querySt("if_height", e.data);
var w = querySt("if_width", e.data);
if (!isNaN(h) && h > 0 && h !== if_height) {
// Height has changed, update the iframe.
iframe.height(if_height = h);
}
if (!isNaN(w) && w > 0 && w !== if_width) {
// Height has changed, update the iframe.
iframe.width(if_width = w);
}
//For debugging only really- can remove the next line if you want
$('body').prepend("Recieved" + h + "hX" + w + "w .. ");
// An optional origin URL (Ignored where window.postMessage is unsupported).
//Here you must put the other domain.com name only! This is like an authentication to prevent spoofing and xss attacks!
}, 'http://www.OTHERDOMAIN.co.uk');
});
オプション3
それらは現在、クロスドメインiFrameのサイズ変更を管理するための小さなJSライブラリであり、iFrameにJavaScriptを少し含める必要がありますが、これは依存関係のないネイティブJSのわずか2.8k(765バイトGzip)です。親ページから呼び出されるまで何もしません。これは、他の人のシステムの素敵なゲストであることを意味します。
このコードは、mutationObserverを使用してDOMの変更を検出し、サイズ変更イベントも監視して、iFrameがコンテンツに合わせたサイズのままになるようにします。IE8 +で動作します。