I'm trying to determine if any iframe is cross-domain or not. According to the accepted answer in this question: Detect when iframe is cross-domain, then bust out of it it says to put the code accessing the contentDocument
of the iframe in a try / catch
block. I tried this for a cross-domain iframe in Chrome:
try { document.getElementsByTagName('iframe')[0].contentDocument; } catch(err){ console.log("called"); }
and it still throws the cross-domain error and does not catch the error.
I also tried to check if the protocol + host + port of the parent page url is in the src
of the iframe:
function thirdPartyIframe(iframe){ var url = document.location.protocol + "//" + document.location.hostname + (document.location.port === "" ? "" : ":" + document.location.port); var regexp = new RegExp(url.replace(/\//g, "\\/").replace(/\./g, "\\.")); if (iframe.src === '' || regexp.test(iframe.src)){ return false; } else { return true; } }
but this does not seem to work for the first iframe on the homepage of Facebook with src
equal to (it's long):
"http://www.facebook.com/ai.php?aed=AQLlH2cfdnsnLrDUVyqrQPlWpayw9N09Z_iNuhulevbeEfVa4mcVRcT8cjAZOjQb8y1QXab5Ae3aSEJx49U_Qv35rtSp1VC9cY0_CrpOjMDk40hS_Xm57A996YtRVCcWSuRZ_jZERQ_iA_E4621NAbKHT9dsB7uElkRtTvl5K-zPI0jeH-BEnlZIOXbeEdbRC6qCwoToaltolpe-Ot2KWgkfb_vBZYpzUc3jQoEHzLG6tauO9l_hkXpYpHxnt-KYFKIFZ1PgmrHgb0UcGjeKHl7yBR1AbW2n5XgdgaAhFvBjs5GZlKy566nvl8eLRA60orwkwtWYeN8-gKoAmOLm7-6minsWn8lk1h2Qn3p07HCTSnYHfv1aJ6mF5jmuzP0YYe7Ym9ZbmK-tvax4uPAQJ2OdULilKbEh8M-2V9pVY3AC228OPlrRullZuuOg8DI2A8WeMF-fbbOdOFFVCe5Gj1CaZu3LYXiqdG7mUgY6AEpk9ZzGT4fC2K8DInQo1AypCvzG64C_bEWfODeXe0aGbkWwsUUmO7E5HFg0tvZkK5IAR_xxxQ2rlf5jbcEDo_2gdIDdHe1HT75-SJLUsSA0M8EU01oNNPuWwEC2BW6inepc9QPuqeg42tcEbKLU-rIUnXDBLvgutft8azWPPQ6_LafGjCAmC9uTalagoWLLDMpQOThvPg7YeVd7qg_c9Mzn2GAfuswcxDSxyRIZo9MaOhA6mhfXeE1tmjyBBsMxnx08tO21Jsfgch59fmMxpeJzdsNMPK3FAojfglvCQ2Zrt_6ataexUB4xlM7_PhKrfBPtxb5fe2TE9-nlWruNEpoCrzI05yv4Go3CYEWHob06K_9iICfNVTFkSYGTiJnMXCy_fdgfyzUIn5QJIPRo4-Wnyg444zKAO_nyFW59LqbIanHVfFY6ybiA6KeC3meREWzTPSsrU5d_NbYHlJWb8uPNDR04jaH5e2qiYj3Y8qgLQA5m"
My function classifies it as not a third party iframe, but Chrome still throws the cross-domain error when I access its contentDocument
.
I'm looking for a foolproof, cross-browser way to do this.
to select the iframe with querySelector . Then we define the canAccessIFrame function that checks if the iframe has the contentDocument property defined. If it's defined then it's not a cross-domain iframe or it's cross domain and cross domain is allowed. Otherwise, false is returned.
A page inside an iframe is not allowed to access or modify the DOM of its parent and vice-versa unless both have the same origin. So putting it in a different way: document or script loaded from one origin is prevented from getting or setting properties of a document from another origin.
To access cross-domain iframe, the best approach is to use Javascript's postMessage() method. This method provides a way to securely pass messages across domains.
Cross-origin communication in between iframe and it's parent website. Yes, it's not any hack or something, but with simple functions you can communicate in between iframe and it's parent website.
You need to do a little more than what's in your try/catch to handle different browsers and to handle different ways that browsers deal with cross domain access:
function canAccessIFrame(iframe) { var html = null; try { // deal with older browsers var doc = iframe.contentDocument || iframe.contentWindow.document; html = doc.body.innerHTML; } catch(err){ // do nothing } return(html !== null); }
In your example, this would be:
var accessAllowed = canAccessIFrame(document.getElementsByTagName('iframe')[0]);
Working demo: http://jsfiddle.net/jfriend00/XsPL6/
Tested in Chrome 21, Safari 5.1, Firefox 14, IE7, IE8, IE9.
A more shorter and more readable function for modern browsers
function canAccessIframe(iframe) { try { return Boolean(iframe.contentDocument); } catch(e){ return false; } }
Tested with Chrome 79 and Firefox 52 ESR.
Explanation: you can check any iframe property that is not accessible cross-origin and convert to boolean. example: contentDocument / contentWindow.document / location.href / etc.
Boolean docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With