How to call javascript after frame is fully rendered? - javascript

I am looking for a way to modify an iFrame attribute (a textbox value actually). The iFrame is on another domain and I do have access to it. From what I understand I must do that after the entire page (iFrame included) is rendered. I tryed something like that:
<script type="text/javascript">
$(window).load(function() {
alert("test");
d = document.getElementById("myframe");
d.contentWindow.document.getElementById("frametxtbox");
});
</script>
But I always get the following error:
Cannot call method 'getElementById' of undefined
I also noticed that the alert pops up BEFORE the iFrame is rendered, so I think my script is executed before page has access to frame values and, therefore I get the error. I have very few knowledge of web-related programming (always worked on backend side) so forgive me if my question maybe makes no sense.

If the iframe points to another domain, it'll be subject to same origin policy. This means that before you try to access its document you'll have to check the wiki and relax the policy (check the link for details). After that you'll need to bind ready event to the iframes document, rather than your main page doc.
$(window.frames['myframe'].document).ready(function() { alert('moo'); });
See if this helps :)

Related

Detect when an iframe returns from a cross domain site

I have an iframe on my page that submits a form to a third party page. Once that third party is done with its calculation, it redirects back to my own site. I would like to detect when the iframe returns back to my own site.
My current approach is to use a timeout and check location.host of the iframe every 0.5 seconds. However, while the iframe is still on the third party site, I get a JS error, which I would like to avoid.
Is there a good way to figure out when the iframe's location is back on my own server without getting a JS error?
function check() {
try {
location.host; // if I error, doStuff() is never hit.
doStuff();
} catch( e ) {
setTimeout(check, 5000);
}
}
Using a try / catch statement should solve this issue for you. There are likely other ways around this, however after reviewing your question this was the first that came to mind.
Another alternative is to listen for the onload event from the iframe. This (in chrome at least) fires each time the iframe page changes. http://jsfiddle.net/rlemon/DwVJX/1/ here is a quick demo. In the iframe click on the jsFiddle logo to go back to the homepage. I understand this doesn't tell you IF you're on the right domain or not, but in conjunction with the try/catch this eliminates the need for a timer.
You could wrap your check in a try catch block. Alternatively you could have the page which is on your host 'call' the parent. (something like parent.notifyReady() ) That way you avoid having to use a setInterval
You could base your logic on whether to call the parent or not by using the document.referrer property
So on your third page you could have something like this:
if(document.referrer.indexOf('otherdomain.com') != -1) {
// script called via otherdomain.com
parent.notifyReady();
}
I think what you are currently doing is the only way to reliably detect whether an iframe is or isn't on a page hosted on your parent page's domain.
Most iframe properties are inaccessible (throw an exception when accessed) while the iframe is on a different domain than the parent. An exception is actually an indication that the iframe IS NOT on your site, so simply catch the exception and try again. If no exception is thrown, the iframe is on a page that is in the same domain as it's parent.

Is it possible to use jQuery to grab the HTML of another web page into a div?

I am trying to integrate with the FireShot API to given a URL, grab HTML of another web page into a div then take a screenshot of it.
Some things I will need to do after getting the HTML
grab <link> & <script> from <head>
grab <body> into <div>
But 1st, it seems when I try to do a
$.get("http://google.com", function(data) { ... });
I get a 200 in firebug colored red. I think it has to do with sites not allowing you to grab their page with JS? Then is opening a window the best I can do? But how might I control the other page with jQuery or call fsapi on that page?
UPDATE
I tried to do something like below to do something when the new window is ready, but FireBug says "Permission denied to access property 'document'"
w = window.open($url.val());
setTimeout(function() { // if I dont do this, I always get about:blank, is there a better way around this?
$(w.document).ready(function() {
console.log(w.document.body);
});
}, 1000);
I believe the cross-site security setup within Javascript is basically blocking this. You'd likely have to proxy the content through your own domain.
There are a couple other options I think for break the cross-site security constraints, but I'm not sure I'd promote them.
If the "another page" locates within the same domain of your hosting page, yes, you can. Please refer to jQuery's $().load() API.
Otherwise, you're disallowed to do so by the browser's Cross-Site Security Policy. At this moment, you can choose to use iFrame instead of DIV.
Some jQuery plugins, e.g. thickbox provides ability to load pages to appropriate container automatically.
Unless I am correct, I do not believe you can AJAX a page cross domain (e.g. from domain1.com to domain2.com). To get around this, you can have a PHP "proxy" script that does the "getting" of the page and then pass it to JS.
For example, in JS you would get() http://mydomain.com/get/?domain=http://google.com and then do what you need to do!

Call the function only after the browser is fully redirected?

<script>
function test() {
alert("this should only be called after the browser is fully redirected?");
}
window.location = "http://google.com";
test();
</script>
I'm about redirecting the user guys to a page and I want to do something (call a function) only after the browser is fully redirected but I can't get it to work. Is there any way for me to do so?
Is there any way for me to do so?
Nope. When the page has opened google.com, you no longer have any control over the browser window.
Once URL changes, all execution of the current page is stopped.
Not really. You'd have to put the page you were redirecting in a frame and keep the script in another frame, then watch for the content frame to get updated. But you'd also run into cross-domain issues because of the Same Origin Policy (which governs access to one document's contents [the new page] from another document [the one containing the script you're running]). So basically, you can't do this.
If you post a separate question saying what you're trying to achieve by running more code afterward, it may be that people can help you with alternative approaches.
i don't believe this would work. it's a form of XSS/injection and therefore a security risk. i don't think the W3C allowed this sort of thing because it's very dangerous. as soon as the user is loading a different page, the browser ignores the previous one.
http://www.coderanch.com/t/439675/HTML-JavaScript/Javascript-call-AFTER-redirect
see that guy's answer for a visual

Permission issues checking if parent site is my parent domain within iframe

I've read several of the questions on this but am still a little confused.
For example: OK, I can't post examples because of hyperlink limitations
Here is my exact situation.
I have a site at mydomain.com
One of the pages has an iframe to another page at sub.mydomain.com
I am trying to prepare an onload script that if the page is not in an iframe or the parent domain of the page containing the iframe is not mydomain.com then redirect to mydomain.com.
After the initial permission issues I realised the problem with sub domains counting as separate domains.
One of the posts above says that "could each use either foo.mydomain.com or just mydomain.com"
So I tried (for testing):
onload="document.domain='mydomain.com';alert(parent.location.href);"
This produced the error (http replaced with lar
Error: Permission denied for <http://sub.mydomain.net> (document.domain=<http://mydomain.net>) to get property Location.href from <http://mydomain.net> (document.domain has not been set).
Source File: http://sub.mydomain.net/?pageID=1&framed=1
Line: 1
Removing the alert produces no errors.
Maybe I am going about this the wrong way since I do not need to interact with the parent just read its domain if there is one.
A nice simple top.domain. For read only there must be a way so that people can prevent their own pages being used within other people's sites.
You can't (easily) do this because of security restrictions.
This answer from #2771397 might point you in the right direction.
OK, while looking at the error console I still had open when I got home a wee lightbulb lit up. I am pretty new to javascript (can you tell ;) but I thought "If it has try/catch"...
well here is a hack at least to get the name of the top domain and an example of how I will use it in my site to show content only if the page is a frame in the correct domain.
Firstly the header will have the following partially PHP generated function:
function getParentDomain()
{
try
{
var wibble=top.location.href;
}
catch(err)
{
if (err.message.indexOf('http://mydomain.com')!=-1)
{
createCookie('IAmAWomble','value')
}
}
}
Basically the value will be something based on the PHP session I think. This will be executed at page load.
If the page is not within the proper site or if javascript is not enabled then the cookie will not be created.
PHP will then attempt to read the correct value from the cookie and show the content or an error message as appropriate.
I do see a slight flaw in this for first visit since page load will run after PHP has generated the content but I'm sure I can work around this somehow. I thought I'd post because this is at least what I was initially asking for and that is a way to read the URL of a parent site if it is in a different domain to the site in the frame.
IIUC you want to use the window.parent attribute: “A reference to the parent of the current window or subframe.”
Assumably, window.parent.document.location.host contains the container page URL domain name.

Cross domain iframe content load detection

I have a rather interesting problem. I have a parent page that will create a modal jquery dialog with an iframe contained within the dialog. The iframe will be populated with content from a 3rd party domain. My issue is that I need to create some dialog level javascript that can detect if the content of the iframe loaded successfully and if it hasn't within a 5 second time frame, then to close the dialog and return the user to the parent page.
I have researched numerous solutions and only two are of any true value.
Get the remote site to include a javascript line of document.domain = 'our-domain.com'.
Use a URL Fragment hack, but again I would need the request that the remote site
able to modify the URL by appending '#some_value' to the end of the URL and my dialog window would have to poll the URL until it either sees it or times out.
Are these honestly the only options I have to work with? Is there not a simpler way to just detect this?
I have been researching if there's a way to poll for http response errors, but this still remains confined to the same restrictions.
Any help would be immensely appreciated.
Thanks
The easiest way (if you can get code added to the external sites) is to have them add an invisible iframe pointing to a special html file on your domain. This could then use parent.parent.foo() to notify the original window about the load event.
Listening for the "load" event will only tell you if the window loaded, not what was loaded or if the document is ready for interaction.
Nicholas Zakas has an article about detecting if an iframe loaded: http://www.nczonline.net/blog/2009/09/15/iframes-onload-and-documentdomain/. Basically you have this code snippet:
var iframe = document.createElement("iframe");
iframe.src = "simpleinner.htm";
if (iframe.attachEvent){
iframe.attachEvent("onload", function(){
alert("Local iframe is now loaded.");
});
} else {
iframe.onload = function(){
alert("Local iframe is now loaded.");
};
}
document.body.appendChild(iframe);
I haven't tested it, but I'm pretty sure jQuery should be able to handle it by doing something like $("#iframe").load(function () { alert("Local iframe is now loaded."); });
You could try using postMessage for communication between frames.
This will require the remote site to include some specific JavaScript to post a message to the parent document when it has finished loading.
It's possible to do this with an onload handler on the iframe itself. Unfortunately (surprise!) IE makes it difficult. The only way I could get this to work was to compose HTML for the iframe, then append it to the document with innerHTML. Then I have to poll to see when the iframe appears in the DOM, which varies depending on if the page is loading. Here's a link to the source: http://svn.openlaszlo.org/openlaszlo/trunk/lps/includes/source/iframemanager.js
See create(), __finishCreate() and gotload(). Feel free to take a copy of this and use it yourself!
Regards,
Max Carlson
OpenLaszlo.org
This is how I detected the loading of a Cross-Domain Iframe,
Set a unique id for the iframe ( U may use any sort of identifier, it doesn't matter )
<iframe id="crossDomainIframe" src=""> </iframe>
Set window event listener:
document.getElementById("crossDomainIframe").addEventListener('load',
function actionToPerform(){
//Do your onLoad actions here
}
)
In any case you will need some sort of cooperation from the other domain's server, as you are trying to abuse the Same Origin Policy (SOP)
The first solution document.domain=... won't work if domains are different. It works only for subdomains and ports, as described in the link above.
The only option that allows cross domain communication without polling is JSONP or script injection with a JS function callback. This method is available in all Google APIs and works well.
We've explained on our blog a way to sandbox those calls in an iframe to secure them. While postMessage is better now, the window.name hack has the advantage of working on old browsers.
Ironically, SOP does not prevent you to POST anything to another domain. But you won't be able to read the response.

Categories