Is there any good way to detect when a page isn't going to display in a frame because of the X-Frame-Options header? I know I can request the page serverside and look for the header, but I was curious if the browser has any mechanism for catching this error.
6 Answers
Answers 1
OK, this one is old but still relevant.
Fact: When an iframe loads a url which is blocked by a X-Frame-Options the loading time is very short.
Hack: So if the onload occurs immediately I know it's probably a X-Frame-Options issue.
Disclaimer: This is probably one of the 'hackiest' code I've written, so don't expect much:
var timepast=false; var iframe = document.createElement("iframe"); iframe.style.cssText = "position:fixed; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;"; iframe.src = "http://pix.do"; // This will work //iframe.src = "http://google.com"; // This won't work iframe.id = "theFrame"; // If more then 500ms past that means a page is loading inside the iFrame setTimeout(function() { timepast = true; },500); if (iframe.attachEvent){ iframe.attachEvent("onload", function(){ if(timepast) { console.log("It's PROBABLY OK"); } else { console.log("It's PROBABLY NOT OK"); } }); } else { iframe.onload = function(){ if(timepast) { console.log("It's PROBABLY OK"); } else { console.log("It's PROBABLY NOT OK"); } }; } document.body.appendChild(iframe);
Answers 2
Disclaimer: this answer I wrote in 2012(Chrome was version ~20 at that time) is outdated and I'll keep it here for historical purposes only. Read and use at your own risk.
Ok, this is a bit old question, but here's what I found out (it's not a complete answer) for Chrome/Chromium.
the way do detect if a frame pointing to a foreign address has loaded is simply to try to access its contentWindow or document.
here's the code I used:
element.innerHTML = '<iframe class="innerPopupIframe" width="100%" height="100%" src="'+href+'"></iframe>'; myframe = $(element).find('iframe');
then, later:
try { var letstrythis = myframe.contentWindow; } catch(ex) { alert('the frame has surely started loading'); }
the fact is, if the X-Frame-Options forbid access, then myFrame.contentWindow
will be accessible.
the problem here is what I called "then, later". I haven't figured out yet on what to rely, which event to subsribe to find when is the good time to perform the test.
Answers 3
This is how I had checked for X-Frames-Options for one of my requirements. On load of a JSP page, you can use AJAX to send an asynchronous request to the specific URL as follows:
var request = new XMLHttpRequest(); request.open('GET', <insert_URL_here>, false); request.send(null);
After this is done, you can read the response headers received as follows:
var headers = request.getAllResponseHeaders();
You can then iterate over this to find out the value of the X-Frames-Options. Once you have the value, you can use it in an appropriate logic.
Answers 4
The only thing I can think of is to proxy an AJAX request for the url, then look at the headers, and if it doesn't have X-Frame-Options, then show it in the iframe. Far from ideal, but better than nothing.
Answers 5
At least in Chrome, you can notice the failure to load because the iframe.onload event doesn't trigger. You could use that as an indicator that the page might not allow iframing.
Answers 6
This can be achieved through
a) Create a new IFrame through CreateElement
b) Set its display as 'none'
c) Load the URL through the src attribute
d) In order to wait for the iframe to load, use the SetTimeOut method to delay a function call (i had delayed the call by 10 sec)
e) In that function, check for the ContentWindow length.
f) if the length > 0, then the url is loaded else URL is not loaded due to X-Frame-Options
Below is the sample code:
function isLoaded(val) { var elemId = document.getElementById('ctlx'); if (elemId != null) document.body.removeChild(elemId); var obj= document.createElement('iframe'); obj.setAttribute("id", "ctlx"); obj.src = val; obj.style.display = 'none'; document.body.appendChild(obj); setTimeout(canLoad, 10000); } function canLoad() { //var elemId = document.getElementById('ctl100'); var elemId = document.getElementById('ctlx'); if (elemId.contentWindow.length > 0) { elemId.style.display = 'inline'; } else { elemId.src = ''; elemId.style.display = 'none'; alert('not supported'); } }
0 comments:
Post a Comment