How to detect if an iframe is accessible without triggering an error?
Try this:
var $frame = $("#frameId"); // swap with the id of the iframe
try {
var canAccess = $frame.contents();
if(!!canAccess) {
// same domain yay you have access
// do your thing here
}
}
catch( e ) {
// bummer can't do much with it
return false;
}
EDIT: add a try and catch, no error will return false.
The jQuery approach can also be done with regular JS:
function iframe_accessible(theiframe) {
var thedoc, debug=true;
try{
thedoc = (theiframe.contentWindow || theiframe.contentDocument);
if (thedoc.document)
thedoc = thedoc.document;
if (debug)
console.log('Accessible');
return true;
}
catch(err) {
if (debug)
console.log("Not accessible because of\n" + err);
return false;
}
}
var elm = document.querySelector('iframe'); // If it exists, of course
console.log(iframe_accessible(elm));
If you can add a little JavaScript to all of the pages from your domain you'd like to load in the iframe you could use window.postMessage
, which is exempt from the Same Origin Policy. Probably the simplest way would be to have the child window post a message to the parent when it loads and use that instead of onload
. For example, you could add this to each page:
if (window.parent) document.addEventListener( 'load', function() {
window.parent.postMessage( "child loaded", "/" );
}, false );
That will post a message to the parent window whenever the page is loaded in a frame with the same origin. You would then listen for it like this:
var iframe = document.getElementById( 'your-iframe' );
var origin = window.location.protocol + '://' + window.location.host;
if (window.location.port != 80) origin += ':' + window.location.port;
window.addEventListener( 'message', function (event) {
if (event.source != iframe.contentWindow
|| event.origin != origin || event.data != "child loaded")
return;
// do here what you used to do on the iframe's load event
}, false );
Note that the examples use the W3C/Netscape event API and thus won't work in Internet Explorer before version 9.