Javascript callback when IFRAME is finished loading? - javascript

I need to execute a callback when an IFRAME has finished loading. I have no control over the content in the IFRAME, so I can't fire the callback from there.
This IFRAME is programmaticly created, and I need to pass its data as a variable in the callback, as well as destroy the iframe.
Any ideas?
EDIT:
Here is what I have now:
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);
});
}
This callsback before the iFrame has loaded, so the callback has no data returned.

First up, going by the function name xssRequest it sounds like you're trying cross site request - which if that's right, you're not going to be able to read the contents of the iframe.
On the other hand, if the iframe's URL is on your domain you can access the body, but I've found that if I use a timeout to remove the iframe the callback works fine:
// 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);
});

I am using jQuery and surprisingly this seems to load as I just tested and loaded a heavy page and I didn't get the alert for a few seconds until I saw the iframe load:
$('#the_iframe').load(function(){
alert('loaded!');
});
So if you don't want to use jQuery take a look at their source code and see if this function behaves differently with iframe DOM elements, I will look at it myself later as I am interested and post here. Also I only tested in the latest chrome.

I have had to do this in cases where documents such as word docs and pdfs were being streamed to the iframe and found a solution that works pretty well. The key is handling the onreadystatechanged event on the iframe.
Lets say the name of your frame is "myIframe". First somewhere in your code startup (I do it inline any where after the iframe) add something like this to register the event handler:
document.getElementById('myIframe').onreadystatechange = MyIframeReadyStateChanged;
I was not able to use an onreadystatechage attribute on the iframe, I can't remember why, but the app had to work in IE 7 and Safari 3, so that may of been a factor.
Here is an example of a how to get the complete state:
function MyIframeReadyStateChanged()
{
if(document.getElementById('myIframe').readyState == 'complete')
{
// Do your complete stuff here.
}
}

The innerHTML of your iframe is blank because your iframe tag doesn't surround any content in the parent document. In order to get the content from the page referred to by the iframe's src attribute, you need to access the iframe's contentDocument property. An exception will be thrown if the src is from a different domain though. This is a security feature that prevents you from executing arbitrary JavaScript on someone else's page, which would create a cross-site scripting vulnerability. Here is some example code the illustrates what I'm talking about:
<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>
To further the example, try using this as the content of the iframe:
<h1>Child</h1>
Google
<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>

I wanted to hide the waiting spinner div when the i frame content is fully loaded on IE, i tried literally every solution mentioned in Stackoverflow.Com, but with nothing worked as i wanted.
Then i had an idea, that when the i frame content is fully loaded, the $(Window ) load event might be fired. And that exactly what happened. So, i wrote this small script, and worked like magic:
$(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";
}
});
Hope this helps.

This function will run your callback function immediately if the iFrame is already loaded or wait until the iFrame is completely loaded.
This also addresses the following issues:
Chrome initializes every iFrame with an about:blank page which will have readyState == "complete". Later, it will replace `about:blank with the actual iframe src value. So, the initial value of readyState will not represent the readyState of your actual iFrame. Therefore, besides checking for readyState value, this function also addresses the about:blank issue.
DOMContentLoaded event doesn't work with iFrame. So it uses the load event for running the callback function if iFrame isn't already loaded. The load event is equivalent to readyState == "complete" which has been used to check whether iFrame is already loaded. So, in any scenario, the callback function will run after iFrame is fully loaded.
iFrame src can have redirects and therefore load a page different from the original src url. This function will also work in that scenario.
Pass in your callback function that you want to run when the iFrame finishes loading and the <iframe> element to this function:
function iframeReady(callback, iframeElement) {
const iframeWindow = iframeElement.contentWindow;
if ((iframeElement.src == "about:blank" || (iframeElement.src != "about:blank" && iframeWindow.location.href != "about:blank")) && iframeWindow.document.readyState == "complete") {
callback();
} else {
iframeWindow.addEventListener("load", callback);
}
}

I had a similar problem as you. What I did is that I use something called jQuery. What you then do in the javascript code is this:
$(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();
});
});
It seems as you delete you iFrame before you grab the html from it. Now, I do see a problem with that :p
Hope this helps :).

I have a similar code in my projects that works fine.
Adapting my code to your function, a solution could be the following:
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);
});
}
Maybe you have an empty innerHTML because (one or both causes):
1. you should use it against the body element
2. you have removed the iframe from the your page DOM

I think the load event is right.
What is not right is the way you use to retreive the content from iframe content dom.
What you need is the html of the page loaded in the iframe not the html of the iframe object.
What you have to do is to access the content document with iFrameObj.contentDocument.
This returns the dom of the page loaded inside the iframe, if it is on the same domain of the current page.
I would retreive the content before removing the iframe.
I've tested in firefox and opera.
Then i think you can retreive your data with $(childDom).html() or $(childDom).find('some selector') ...

I've had exactly the same problem in the past and the only way I found to fix it was to add the callback into the iframe page. Of course that only works when you have control over the iframe content.

Using onload attrbute will solve your problem.
Here is an example.
function a() {
alert("Your iframe has been loaded");
}
<iframe src="https://stackoverflow.com" onload="a()"></iframe>
Is this what you want?
Click here for more information.

Related

How to remove HTML script tag with open type [duplicate]

How can I remove script elements before they are being executed?
I thought about using the DOMNodeInserted event, but apparently it doesn't catch script elements. I've also tried using the jQuery livequery plugin like that:
$("script").livequery(function () {
$(this).remove();
});
It did remove the script element, but after it was executed.
I'm looking for a cross-browser solution, but I'm not even sure if that's possible. I read about Mutation Observers which seems close enough but I'm not sure if it can solve my problem.
It would be even better if there was a way to modify the script content before it is being executed without removing and recreating it.
Removing a script element does not do anything. If you can somehow access a script element, it was executed a long time ago and removing it will have no effect.
So we need to work around it. If your script element is at the top of the page like this:
<head>
<script src="yourscript.js"></script>
You could make a synchronous ajax request to the same page, so you can parse its content into a new document, modify all script tags and then replace
the current document with the modified document.
var xhr = new XMLHttpRequest,
content,
doc,
scripts;
xhr.open( "GET", document.URL, false );
xhr.send(null);
content = xhr.responseText;
doc = document.implementation.createHTMLDocument(""+(document.title || ""));
doc.open();
doc.write(content);
doc.close();
scripts = doc.getElementsByTagName("script");
//Modify scripts as you please
[].forEach.call( scripts, function( script ) {
script.removeAttribute("src");
script.innerHTML = 'alert("hello world");';
});
//Doing this will activate all the modified scripts and the "old page" will be gone as the document is replaced
document.replaceChild( document.importNode(doc.documentElement, true), document.documentElement);
Unfortunately this cannot be set up in jsfiddle or jsbin. But you should be able to copy paste this code exactly as it is into this
page's console in google chrome. You should see the alerts and when you inspect the live dom, each script was modified.
The difference is that we are running this after scripts have been executed on the page, so the old scripts should still have a working effect on the page.
That's why, for this to work, you need to be the very first script on the page to do it.
Tested to work in google chrome. Firefox is completely ignoring the doc.write call for some reason.
i donot know what you are trying to do. But it is better to load them on request rather than delete on some conditions.
$.getScript('helloworld.js', function() {
$("#content").html('
Javascript is loaded successful!
');
});
If you wants to remove scripts before there execution, its not possible.
But what you can do is, remove script programatically on a condition & if have an issue with memory-leaks, then you can call below code before remove script.
var var1 = 'hello';
var cleanAll = function () {
delete window.var1;
delete window.cleanAll;
};
// unload all resources
cleanAll();

JS Keep loading till img src changed

I want to monitor an unmount event on my NAS.
it has a seperate page to unmount all usb drives.
I've included it via iframe and want to keep the site loading until the image source has been changed to a specific source (a green bar, indicating that it has done unmounting).
The reason why I want to keep it loading is because im calling it via a jquery.get function from another site, and i want it to wait till the unmounting process is done.
Would be great if this is possible only in plain javascript, but if needed I can also include jquery.
Here is what I got so far:
<script type="text/javascript">
function check(){
if (!(document.getElementById("uiView_TestPic").src == "/css/default/images/finished_ok_green.gif")){
window.setTimeout(check(), 2000);
}else{
alert("Done!");
}}
window.onload(check());
</script></head>
<body>
<iframe seamless width="100%" frameborder="0" height="80%" src="http://fritz.box/usb/usb_diskcut.lua?usbdev=all"></iframe>
I am immediately receiving an error that the element "uiView_TestPic" does not exist, even when I add a timeout before running check.
The included iFrame site stops loading as soon as all images are loading and not when the whole process is done.
First off, both frames must be running on the same domain because browsers will prevent code in one frame from accessing anything in the other frame if they are different domains. If the two frames are not on the same domain, then the iframe will have to monitor itself and notify the other frame when it has finished using something like window.postMessage().
If they are on the same domain, this is slightly complicated. You have to get the iframe element (that's in your main document). You have to wait for that to be ready (since it has to load it's own contents). Then, you have to get the document in the iframe. Then you can find the desired image in the iframe. Then you can observe it's contents. And, of course, you can only do any of this if the iframe is the same domain as your main page (because of security restrictions).
First, add an id to the iframe:
<iframe id="myFrame" seamless width="100%" frameborder="0" height="80%" src="http://fritz.box/usb/usb_diskcut.lua?usbdev=all"></iframe>
Then, you can use this:
// put this code in your document AFTER the iFrame tag
// or only run it after the DOM is loaded in your main document
function checkImageSrc(obj) {
if (obj.src.indexOf("/finished_ok_green.gif") !== -1) {
// found the green gif
// put whatever code you want here
} else {
// check repeatedly until we find the green image
setTimeout(function() {
checkImageSrc(obj);
}, 2000);
}
}
// get the iframe in my documnet
var iframe = document.getElementById("myFrame");
// get the window associated with that iframe
var iWindow = iframe.contentWindow;
// wait for the window to load before accessing the content
iWindow.addEventListener("load", function() {
// get the document from the window
var doc = iframe.contentDocument || iframe.contentWindow.document;
// find the target in the iframe content
var target = doc.getElementById("uiView_TestPic");
checkImageSrc(target);
});
FYI, there's more detail on waiting for an iframe to be ready here: How can I access the DOM elements within an iFrame
If you control the code in the iframe, then a much cleaner way to implement this would be to use window.postMessage() to post a message to the parent window when the code in the iframe finishes its operation. Then the parent window can just listen for that single message and it will know when the operation is done.
That could look something like this. Put this code in the iframe:
// put this code in your document AFTER the relevant image tag
// or only run it after the DOM is loaded in your iframe
// if you can hook into the actual event that knows the unmount
// is done, that would be even better than polling for the gif to change
function checkImageSrc(obj) {
if (obj.src.indexOf("/finished_ok_green.gif") !== -1) {
// found the green gif
// notify the parent
window.parent.postMessage("unmount complete", "*");
} else {
// check repeatedly until we find the green image
setTimeout(function() {
checkImageSrc(obj);
}, 2000);
}
}
// find the target in the iframe content
var target = document.getElementById("uiView_TestPic");
checkImageSrc(target);
Then, in your main window, you would listen for the posted message like this:
window.addEventListener("message", function(e) {
// make sure this is coming from where we expect (fill in the proper origin here)
if (e.origin !== "http://example.org:8080") return;
if (e.data === "unmount complete") {
// unmount is complete - put your code here
}
});
You can check whether the element is there in the dom or not and then have the check for the src. Something like this should work:
function check(){
if (document.getElementById("uiView_TestPic") && !(document.getElementById("uiView_TestPic").src == "/css/default/images/finished_ok_green.gif")){
window.setTimeout(check(), 2000);
}else{
alert("Done!");
}}
window.onload(check());
In this Fiddle you will see that src null error is not happening. However if you remove document.getElementById("uiView_TestPic") && you get your error

Why is iframe.contentWindow == null?

I use the following code to dynamically create an iframe.
var iframe_jquery = $("<iframe>")
.addClass("foo")
.appendTo(container); // container is a jQuery object containing a <div> which already exists
Then, I want to access its contentWindow, but it's null:
var iframe = iframe_jquery.get(0);
if (iframe){ // iFrame exists
console.log(iframe.contentWindow); // Prints "null"
var doc = iframe.contentWindow.document; // NullpointerException
}
So I thought: "Maybe the iframe isn't ready yet?" So I tried:
iframe_jquery.ready(function(){
var iframe = iframe_jquery.get(0);
console.log(iframe.contentWindow); // Prints "null"
var doc = iframe.contentWindow.document; // NullpointerException
});
Same result.
What's wrong?
I had this problem last week while playing with iframes (building an rtf editor), and yeah it's not ready yet.
I thought if I put it in a .ready(), it would work, but .ready() is when the DOM is ready, not when the iframe has loaded its contents, so I ended up wrapping my code with jQuery .load().
So try this:
$(function () {
$("#myiframe").load(function () {
frames["myframe"].document.body.innerHTML = htmlValue;
});
});
Hope this helps
The problem is that your <iframe> won't be "real" until it's really added to the actual DOM for the page. Here is a fiddle to demonstrate..
Depending on the browser, accessing the document or an <iframe> may vary.
Here is an example of how to handle it:
if (iframe.contentDocument) // FF Chrome
doc = iframe.contentDocument;
else if ( iframe.contentWindow ) // IE
doc = iframe.contentWindow.document;
You can also make a function that will be executed when the iframe has finished loading by setting it's onload attribute.
Bookmarklet version
Just out of curiosity I thought I'd put this together. Remembering that iframes and load events don't play well together on different browsers (mainly older, falling apart, should-be-dead browsers)... plus not being entirely sure how jQuery gets around this problem... my brain decided that this would be better supported (whether it is or not is neither here nor there):
$(function(){
/// bind a listener for the bespoke iframeload event
$(window).bind('iframeload', function(){
/// access the contents of the iframe using jQuery notation
iframe.show().contents().find('body').html('hello');
});
/// create your iframe
var iframe = $('<iframe />')
/// by forcing our iframe to evaluate javascript in the path, we know when it's ready
.attr('src', 'javascript:(function(){try{p=window.parent;p.jQuery(p).trigger(\'iframeload\');}catch(ee){};})();')
/// insert the iframe into the live DOM
.appendTo('body');
});
The reason for taking this approach is that it is normally far better to trigger your load event from inside the iframe itself. But this means having a proper document loaded in to the iframe, so for dynamic iframes this is a little tedious. This is kind of a mixture between having a document loaded, and not.
The above works on everything I have tested so far - and yes you are correct - it is a little ridiculous, non-future-proof and propably other things that have negative connotations ;)
One positive thing I'll say about this post is that introduces the use of .contents() to access the document of the iframe, which is at least a little bit useful...

How to insert a javascript file into an iframe then call a function in the inserted javascript?

Edit: Just found out this is a chrome problem, the code works fine in firefox
I have an iframe on a webpage that shows a book formatted as html. I would like to insert some javascript within this iframe to make the book more dynamic (e.g. click on sentences, show animations etc). The iframe content is in the same domain as the parent page.
I can insert the javascript into the iframe but get an error calling a function in the inserted javascript. I've described the different bits of code below:
My parent page javascript is:
function iframeLoaded()
{
var iFrameID = document.getElementById('preview-iframe');
var jsLink = iFrameID.contentDocument.createElement("script");
jsLink.src="/tests/iframeAPI.js";
jsLink.type = 'text/javascript';
iFrameID.contentDocument.head.appendChild(jsLink);
iFrameID.contentWindow.initialiseApi()
}
and the html containing the iframe is:
<iframe id="preview-iframe" width="640" height="240" frameborder="0" src="./testpage.htm" onload="iframeLoaded()" scrolling="no"></iframe>
The contents of iframeAPI.js is:
window.initialiseApi = function() { alert("Hello world") }
Looking at the iFrame's html in the browser shows that the iFrameAPI.js tag is inserted ok into the iframe head, but I don't get the alert popup when the page is loaded. The error appears on the following line:
iFrameID.contentWindow.initialiseApi()
Uncaught TypeError: Object [object Window] has no method 'initialiseApi'
However I can run this line in the browser's javascript console and the alert popup works fine.
Any help would be much appreciated.
Thanks,
Brian
Edit: I've just tried with an onload event to make sure the page is loaded and I still have the problem:
My parent page javascript is now :
function iframeLoaded()
{
var iFrameID = document.getElementById('preview-iframe');
var jsLink = iFrameID.contentDocument.createElement("script");
jsLink.src="/tests/iframeAPI.js";
jsLink.type = 'text/javascript';
iFrameID.contentDocument.head.appendChild(jsLink);
jsLink.onLoad= iFrameLoaded();
}
function iFrameLoaded()
{
alert("Iframe loaded"); // Alert works ok
var iFrameID = document.getElementById('preview-iframe');
iFrameID.contentWindow.initialiseApi(); // Same error message on this line
}
It sounds like you are trying to use the function before the content has loaded.
try this instead:
var t = setTimeout(iFrameID.contentWindow.initialiseApi(),500);
This will wait half a second before trying the function which should give the page tiem to load. Delay times are given in milliseconds.
An even better approach is to try using Jquery and its ready() method but this requires the jquery library to be loaded as well. Its well worth it though in my opinion, see http://api.jquery.com/ready/.
You would try something like:
$("body",iFrameID.contentWindow.document).ready(iFrameID.contentWindow.initialiseApi())
You're executing it right away without giving the script a chance to load. Hook up an onload event to your script block and run your main function then.
Try, in the page included in the iFrame, accessing the main page by doing something like:
window.parent.xyz = something;
Where something is what you want exposed to the main page. Could be a function or an object of functions. Now in the main page you can just do:
something(); // or something.somefunction();
You could also send window references, I think, but I have not tried that.
The easiest way is to call the initialiseApi function in the iframeAPI.js itself as it will be called as soon as it's loaded. The iframeAPI.js could look like that:
function initialiseApi() {
alert("Hello world");
}
initialiseApi();
There is no callback or timeout needed.

Event when iframe finishes loading [duplicate]

I need to execute a callback when an IFRAME has finished loading. I have no control over the content in the IFRAME, so I can't fire the callback from there.
This IFRAME is programmaticly created, and I need to pass its data as a variable in the callback, as well as destroy the iframe.
Any ideas?
EDIT:
Here is what I have now:
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);
});
}
This callsback before the iFrame has loaded, so the callback has no data returned.
First up, going by the function name xssRequest it sounds like you're trying cross site request - which if that's right, you're not going to be able to read the contents of the iframe.
On the other hand, if the iframe's URL is on your domain you can access the body, but I've found that if I use a timeout to remove the iframe the callback works fine:
// 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);
});
I am using jQuery and surprisingly this seems to load as I just tested and loaded a heavy page and I didn't get the alert for a few seconds until I saw the iframe load:
$('#the_iframe').load(function(){
alert('loaded!');
});
So if you don't want to use jQuery take a look at their source code and see if this function behaves differently with iframe DOM elements, I will look at it myself later as I am interested and post here. Also I only tested in the latest chrome.
I have had to do this in cases where documents such as word docs and pdfs were being streamed to the iframe and found a solution that works pretty well. The key is handling the onreadystatechanged event on the iframe.
Lets say the name of your frame is "myIframe". First somewhere in your code startup (I do it inline any where after the iframe) add something like this to register the event handler:
document.getElementById('myIframe').onreadystatechange = MyIframeReadyStateChanged;
I was not able to use an onreadystatechage attribute on the iframe, I can't remember why, but the app had to work in IE 7 and Safari 3, so that may of been a factor.
Here is an example of a how to get the complete state:
function MyIframeReadyStateChanged()
{
if(document.getElementById('myIframe').readyState == 'complete')
{
// Do your complete stuff here.
}
}
The innerHTML of your iframe is blank because your iframe tag doesn't surround any content in the parent document. In order to get the content from the page referred to by the iframe's src attribute, you need to access the iframe's contentDocument property. An exception will be thrown if the src is from a different domain though. This is a security feature that prevents you from executing arbitrary JavaScript on someone else's page, which would create a cross-site scripting vulnerability. Here is some example code the illustrates what I'm talking about:
<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>
To further the example, try using this as the content of the iframe:
<h1>Child</h1>
Google
<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>
I wanted to hide the waiting spinner div when the i frame content is fully loaded on IE, i tried literally every solution mentioned in Stackoverflow.Com, but with nothing worked as i wanted.
Then i had an idea, that when the i frame content is fully loaded, the $(Window ) load event might be fired. And that exactly what happened. So, i wrote this small script, and worked like magic:
$(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";
}
});
Hope this helps.
This function will run your callback function immediately if the iFrame is already loaded or wait until the iFrame is completely loaded.
This also addresses the following issues:
Chrome initializes every iFrame with an about:blank page which will have readyState == "complete". Later, it will replace `about:blank with the actual iframe src value. So, the initial value of readyState will not represent the readyState of your actual iFrame. Therefore, besides checking for readyState value, this function also addresses the about:blank issue.
DOMContentLoaded event doesn't work with iFrame. So it uses the load event for running the callback function if iFrame isn't already loaded. The load event is equivalent to readyState == "complete" which has been used to check whether iFrame is already loaded. So, in any scenario, the callback function will run after iFrame is fully loaded.
iFrame src can have redirects and therefore load a page different from the original src url. This function will also work in that scenario.
Pass in your callback function that you want to run when the iFrame finishes loading and the <iframe> element to this function:
function iframeReady(callback, iframeElement) {
const iframeWindow = iframeElement.contentWindow;
if ((iframeElement.src == "about:blank" || (iframeElement.src != "about:blank" && iframeWindow.location.href != "about:blank")) && iframeWindow.document.readyState == "complete") {
callback();
} else {
iframeWindow.addEventListener("load", callback);
}
}
I had a similar problem as you. What I did is that I use something called jQuery. What you then do in the javascript code is this:
$(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();
});
});
It seems as you delete you iFrame before you grab the html from it. Now, I do see a problem with that :p
Hope this helps :).
I have a similar code in my projects that works fine.
Adapting my code to your function, a solution could be the following:
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);
});
}
Maybe you have an empty innerHTML because (one or both causes):
1. you should use it against the body element
2. you have removed the iframe from the your page DOM
I think the load event is right.
What is not right is the way you use to retreive the content from iframe content dom.
What you need is the html of the page loaded in the iframe not the html of the iframe object.
What you have to do is to access the content document with iFrameObj.contentDocument.
This returns the dom of the page loaded inside the iframe, if it is on the same domain of the current page.
I would retreive the content before removing the iframe.
I've tested in firefox and opera.
Then i think you can retreive your data with $(childDom).html() or $(childDom).find('some selector') ...
I've had exactly the same problem in the past and the only way I found to fix it was to add the callback into the iframe page. Of course that only works when you have control over the iframe content.
Using onload attrbute will solve your problem.
Here is an example.
function a() {
alert("Your iframe has been loaded");
}
<iframe src="https://stackoverflow.com" onload="a()"></iframe>
Is this what you want?
Click here for more information.

Categories

Resources