Jquery/javascript detection if iframe can be loaded - javascript

I have iframes with OpenX ads I server from another server/domain.
When something happens to this ad server the main server doesn't load whole contents because the domain that openx loads in iframe is not responding. I always thought that iframe works independently from the main site but it doesn't if the domain doesn't answer at all...
Anyway can main site detect somehow that a url in iframe is not responding and skips loading iframe and show the rest of the site?

How about loading the iFrame once the website is loaded? It's pretty easy to do this using jQuery (or even plain javascript using the window.load event).
So rather than wanting to 'detect' whether the iFrame has loaded, you can load it AFTER the rest of the website has completed loading. (sorry for excessive use of word 'load')
In jQuery, you can simply attach the url to the iFrame on the document.ready event.
A blank iFrame
<iframe id="iframe-ad" width="200"></iframe>
Simple jQuery to load the URL on document.ready
<script type="text/javascript">
$(document).ready(function() {
$("#iframe-ad").attr("src", "http://www.google.com");
});
</script>

Unfortunately there is no easy way to do this unless they are served from the same domain. I know there is a way to get let the javascript inside the iframe perform some actions on the parent document it is contained in, but I am not really sure how...

It is not possible, because of Same origin policy, there are some "gaps" in some browsers. But this is not going to recommend!

Might not make for the best experience, but you can make a local redirect file. something like:
<iframe src="http://www.mydomain.com/redir?url=http://www.theirdomain.com/ads"/>
then the redir page just returns
<script>
location.href = "${url}";
</script>
That way as long as your server is responding, everything else will continue as normal while the iframe redirects?

How about if I don't have iframe just javascript originating from different domain? If the domain is not responding javascript holds the page back not to load. Is there a way to prevent that?

Related

Wistia E-v1.js script being loaded twice

So I am calling the wistia script with a script tag in my head like this:
<script charSet='ISO-8859-1' src='//fast.wistia.com/assets/external/E-v1.js' async defer data-script='wistia' />
However, when I check out the network tab on Chrome, I notice that the E-v1.js script from Wistia is being loaded twice, which is rather significant as it is a 273kb script.
The first load of the script is from https://fast.wistia.com/assets/external/E-v1.js, the location to which I have called it.
However, the second load of the script comes from an iframe, despite me not having put any iframes on the page. This iframe calls the script even on webpages which do not contain any wistia videos. The referrer is: https://fast.wistia.com/embed/iframe_shim?domain=com.
What's going on here? I assume this is some trying-to-be-helpful behaviour from wistia to lazy load their script via an iframe, but it's already loaded...
So I contacted Wistia and got an answer. Their development practices are not exactly intuitive.
Here's what the guy said:
The iframe_shim is a way of tracking the visitor_key for stats tracking, and storing that information on the fast.wistia domain rather than your domain. For a more lightweight method of doing that, you can set window.wistiaIframeShim = false in script tags on your page, and that will stop E-v1.js from loading again. Visitors will then be tracked via a cookie and localstorage directly on your domain instead of the fast.wistia.com domain. As far as I know this shouldn't be problematic, and we'll eventually be changing how that works to make it more efficient, it just hasn't been prioritized yet.
So they seem to load it twice from two different origins just to store a tiny amount of information on their own domain rather than on the client. Seems ridicuous to me, but I can confirm as of right now that all you have to do is change that window variable.
THE FIX: window.wistiaIframeShim = false

Hide Content via JS Calls

I have a page that is not on the same domain and I want to be able to hide the header and footer when it is loaded in another specific site.
Can this be done using iframe-resizer? I have used it before and it works great but never tried cross communication and think that I will hit a security issue.
I was hoping that I could call postMessage to a JS function on the child page to hide the elements.
Yep I think that using postMessage would work, although you might get a bit of a flash, as it wouldn't be sent until the iFrame had loaded.
You could also look at usings something like if (window.location !== top.location) {...}.

Need to change #src of a parent iframe from within child iframe

I have the following HTML markup (don't ask....)
- document //main site
- <iframe> //my site
- <iframe> //site within my site
- <frame>
- <a onclick="JavaScript:parent.parent.location.href='http://bla.com;return false;'">
Basically, main site is calling my site in an iframe. I, in turn, also have an iframe on my site where I'm calling 3rd site. The third site has a frameset with a frame in it that has a link. When clicking on this link, it has to change the url of my site. My site and my child site are on the same domain. When I'm running my site as "stand-alone" (not in iframe) the above code works fine in all browsers.
Once I open my site in an iframe of the main site, it looks like the above code is trying to change the source of the main site. In FireFox I get a console message "Access to property denied". In IE it opens up a new window with my site not in the main site anymore.
What is the correct JavaScript to change the #src attribute on my site when I'm within an iframe?
You are banging your head against the wall that is the same origin policy here. This is XSS country and strictly forbidden, no way around it, unless both domains agree to talk together.
You can read more about cross domain communication using iframes, but again, unless the different domain agree to talk together, you are out of luck.
Although this might seem frustrating, be glad of this rule next time you use homebanking ;)
Can you try something like this
<document> //main site
<iframe id="my_iframe"> //your site
<iframe> //site within your site
<frame>
<a onclick="JavaScript:Top.document.getElementById('my_iframe').location.href='http://bla.com;return false;'">
Top refers to the main window, and then getElementById('my_iframe') will give you your iframe element.
I believe that you're trying to do communication between different pages.
You may take a look this API: HTML5 Cross Document Messaging
Basically, if you want to tell the parent iframe to navigate to a certain url, you can do this:
In the site within my site html:
// onclick of your anchor, post message (an event) with an expected origin
window.postMessage("http://bla.com", "www.sitewithinmysite.com");
In my site html:
// listen to the event "message"
window.addEventListener("message", messageHandler, true);
function messageHandler(e) {
// only recognize message from this origin
if (e.origin === "www.sitewithinmysite.com") {
// then you can navigate your page with the link passed in
window.location = e.data;
}
}
You might want to have the pages communicate using AJAX. Have the site that needs to change its URL listen by long polling to to a node.js server.

Is is possible to make ajax calls from a bookmarklet?

I plan to create a bookmarklet which users will use to share content (bacially url's and page title) around the web on say mysite.com. So this is what I am following till now:
Bookmarklet calls an external.js which basically contains all the logic
external.js can either a) create an iframe or b) open a popup window and pass in the shared url information
Now my question is... is there a possible third approach where the external js file can load everything via ajax from mysite.com. Or since the bookmarklet will share content from other sites this won't work because of same origin policy. And the only way this could work is by making ajax calls from inside the iframe or popup window?
Also is there a preference or downsides for using the popup window vs. iframe approach?
Take a look at the approach used by the Instapaper.com bookmarklet:
javascript:function iprl5(){
var d=document,
z=d.createElement('scr'+'ipt'),
b=d.body,
l=d.location;
try{
if(!b)throw(0);
d.title='(Saving...)'+d.title;
z.setAttribute('src',l.protocol+'//www.instapaper.com/j/xxxxxxxx?u='+encodeURIComponent(l.href)+'&t='+(new Date().getTime()));
b.appendChild(z);
} catch(e) {
alert('Please wait until the page has loaded.');
}
}
iprl5();
void(0)
They in fact use JSONP and insert a script tag on the page.
Your bookmarklet will run in the context of the current page, not your site. So, XHR calls to your site will fail.
In general, an iframe will work better than a popup because of popup blockers.
There are some other clever approaches you can take. Consider a JSONP model. Or, if you only need one way communication (ie, send some data to your site), and you don't care about a response, consider loading a GET request URL as the source of an image. You could even stream back a success or failure image if you wanted to get really fancy.
<img src="http://me.com/AddLink?UserId=123&url=http://you.com&title=Your+Site" />

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