IFRAMEの読み込みが完了したら、コールバックを実行する必要があります。 IFRAMEのコンテンツを制御できないため、そこからコールバックを実行できません。
このIFRAMEはプログラムによって作成され、そのデータをコールバックの変数として渡し、iframeを破棄する必要があります。
何か案は?
編集:
ここに私が持っているものがあります:
function xssRequest(url, callback)
{
var iFrameObj = document.createElement('IFRAME');
iFrameObj.src = url;
document.body.appendChild(iFrameObj);
$(iFrameObj).load(function()
{
document.body.removeChild(iFrameObj);
callback(iFrameObj.innerHTML);
});
}
これは、iFrameがロードされる前にコールバックするため、コールバックにはデータが返されません。
最初に、関数名xssRequestを使用すると、クロスサイトリクエストを試みているように聞こえます-そうだとすると、iframeのコンテンツを読み取ることができなくなります。
一方、iframeのURLがドメイン上にある場合、本文にアクセスできますが、タイムアウトを使用してiframeを削除すると、コールバックが正常に機能することがわかりました。
// possibly excessive use of jQuery - but I've got a live working example in production
$('#myUniqueID').load(function () {
if (typeof callback == 'function') {
callback($('body', this.contentWindow.document).html());
}
setTimeout(function () {$('#frameId').remove();}, 50);
});
私はjQueryを使用していますが、驚いたことに、重いページをテストしてロードしたので、これがロードされているようで、iframeのロードが表示されるまで数秒間アラートが表示されませんでした:
$('#the_iframe').load(function(){
alert('loaded!');
});
したがって、jQueryを使用したくない場合は、ソースコードを見て、この関数がiframe DOM要素で異なる動作をするかどうかを確認します。興味があるので、後で自分で調べてここに投稿します。また、私は最新のクロムでのみテストしました。
Iframeタグは親ドキュメントのコンテンツを囲まないため、iframeのinnerHTMLは空白です。 iframeのsrc属性によって参照されるページからコンテンツを取得するには、iframeのcontentDocumentプロパティにアクセスする必要があります。ただし、srcが別のドメインからのものである場合、例外がスローされます。これは、他の人のページで任意のJavaScriptを実行することを防ぐセキュリティ機能であり、クロスサイトスクリプティングの脆弱性を作成します。以下は、私が話していることを説明するサンプルコードです。
<script src="http://prototypejs.org/assets/2009/8/31/prototype.js" type="text/javascript"></script>
<h1>Parent</h1>
<script type="text/javascript">
function on_load(iframe) {
try {
// Displays the first 50 chars in the innerHTML of the
// body of the page that the iframe is showing.
// EDIT 2012-04-17: for wider support, fallback to contentWindow.document
var doc = iframe.contentDocument || iframe.contentWindow.document;
alert(doc.body.innerHTML.substring(0, 50));
} catch (e) {
// This can happen if the src of the iframe is
// on another domain
alert('exception: ' + e);
}
}
</script>
<iframe id="child" src="iframe_content.html" onload="on_load(this)"></iframe>
さらに例を見るには、これをiframeのコンテンツとして使用してみてください。
<h1>Child</h1>
<a href="http://www.google.com/">Google</a>
<p>Use the preceeding link to change the src of the iframe
to see what happens when the src domain is different from
that of the parent page</p>
WordのドキュメントやPDFなどのドキュメントがiframeにストリーミングされている場合にこれを行う必要があり、非常にうまく機能するソリューションが見つかりました。重要なのは、iframeでonreadystatechanged
イベントを処理することです。
フレームの名前が「myIframe」だとしましょう。まず、コードスタートアップのどこかで(iframeの後の任意の場所でインラインします)、次のようなものを追加してイベントハンドラーを登録します。
document.getElementById('myIframe').onreadystatechange = MyIframeReadyStateChanged;
Iframeでonreadystatechage属性を使用できなかったため、その理由を思い出せませんが、アプリはIE 7およびSafari 3で動作する必要があったため、それが要因となった可能性があります。
完全な状態を取得する方法の例を次に示します。
function MyIframeReadyStateChanged()
{
if(document.getElementById('myIframe').readyState == 'complete')
{
// Do your complete stuff here.
}
}
IフレームのコンテンツがIEに完全に読み込まれたときに、待機中のスピナーdivを非表示にしたかったので、Stackoverflow.Comに記載されているすべてのソリューションを文字通り試しましたが、何もうまくいきませんでした。
それから、iフレームのコンテンツが完全にロードされると、$(Window)loadイベントが発生するかもしれないという考えがありました。そして、まさにそれが起こった。それで、私はこの小さなスクリプトを書き、魔法のように働きました。
$(window).load(function () {
//alert("Done window ready ");
var lblWait = document.getElementById("lblWait");
if (lblWait != null ) {
lblWait.style.visibility = "false";
document.getElementById("divWait").style.display = "none";
}
});
お役に立てれば。
あなたと同じような問題がありました。私がしたことは、jQueryと呼ばれるものを使用することです。次に、javascriptコードで行うことは次のとおりです。
$(function(){ //this is regular jQuery code. It waits for the dom to load fully the first time you open the page.
$("#myIframeId").load(function(){
callback($("#myIframeId").html());
$("#myIframeId").remove();
});
});
Htmlを取得する前にiFrameを削除するようです。今、私はそれに関する問題を見ています:p
お役に立てれば :)。
私のプロジェクトには、うまく機能する同様のコードがあります。私のコードをあなたの関数に適応させると、解決策は次のようになります:
function xssRequest(url, callback)
{
var iFrameObj = document.createElement('IFRAME');
iFrameObj.id = 'myUniqueID';
document.body.appendChild(iFrameObj);
iFrameObj.src = url;
$(iFrameObj).load(function()
{
callback(window['myUniqueID'].document.body.innerHTML);
document.body.removeChild(iFrameObj);
});
}
(1つまたは両方の原因):1. body要素に対して使用する必要がある2.ページDOMからiframeを削除しているため
ロードイベントは正しいと思います。正しくないのは、iframeコンテンツdomからコンテンツを取得する方法です。
必要なのは、iframeオブジェクトのhtmlではなく、iframeにロードされたページのhtmlです。
あなたがしなければならないのは、iFrameObj.contentDocument
でコンテンツドキュメントにアクセスすることです。現在のページと同じドメインにある場合、iframe内にロードされたページのDOMを返します。
Iframeを削除する前にコンテンツを取得します。
私はFirefoxとオペラでテストしました。
その後、$(childDom).html()
または$(childDom).find('some selector') ...
でデータを取得できると思います
私は過去にもまったく同じ問題を抱えていましたが、それを修正する唯一の方法は、iframeページにコールバックを追加することでした。もちろん、iframeコンテンツを制御できる場合にのみ機能します。