2

I'm deploying an application that can be configured to load 3rd-party content in an iframe. If it's pointed to a service that includes X-Frame-Options: SAMEORIGIN or similar, the load request can be blocked transparently by the browser. I'd like to improve the user experience when this happens -- display some useful error message on the page, since most users wouldn't know to check the Javascript console to see why it isn't working.

const frame = document.getElementById("frm"),
  btn1 = document.getElementById("btn1"),
  btn2 = document.getElementById("btn2"),
  txt = document.getElementById("txt");
  
btn1.addEventListener("click", function(){txt.textContent="Loading...";frame.src="https://stackoverflow.com";})
btn2.addEventListener("click", function(){txt.textContent="Loading...";frame.src="https://www.google.com/search?q=hello";})

frame.addEventListener("load", function(evt){txt.innerHTML = txt.innerHTML + "<br/>It loaded!";});

frame.addEventListener("error", function(evt){txt.innerHTML = txt.innerHTML + "<br/>It broke!";});

frame.addEventListener("securitypolicyviolation", function(evt){txt.innerHTML = txt.innerHTML + "<br/>Violation!";});
<iframe id="frm" src="about:blank"></iframe>
<br/>
<button type="button" id="btn1">Load good content</button>
<button type="button" id="btn2">Load bad content</button>
<br/>
<div id="txt"></div>

I have added event listeners to the iframe element for both load and error, but blocked ("bad") requests still fire the load event and nothing will trigger the error handler. How can I make the "error" handler fire when the request is blocked?

ETA: I also added a listener for securitypolicyviolation but that doesn't seem to fire either (at least on latest Chromium).

Coderer
  • 25,844
  • 28
  • 99
  • 154
  • Google use `X-Frame-Options:SAMEORIGIN` so that you can not do load within an iFrame. Its due to CSP.Read the MDN link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options so google rejected the request from different origins. – Ataur Rahman Munna Jul 06 '17 at 12:44
  • I have edited the question to clarify. Please run the snippet, click the "good" button, then click the "bad" button. Note that in both cases the "load" event fires. I would like *some* way to fire an event when the load is blocked by the browser. – Coderer Jul 06 '17 at 12:53
  • Have you tried listening for the `securitypolicyviolation` event? – sideshowbarker Jul 06 '17 at 13:58
  • For Chrome you might also try listening for the `securitypolicyviolation` from the `window` object instead of the `document` object – sideshowbarker Jul 06 '17 at 15:06
  • I tested it in Chrome and Firefox, on `frame`, `document`, and `window`. I couldn't get any combination to work, and documentation about this event seems sparse. I'd really like to see a working example. – Coderer Jul 07 '17 at 09:06
  • It seems the answer is, you can’t catch this cross-origin. See https://stackoverflow.com/questions/6327128/can-i-catch-exception-of-iframe-in-parent-window-of-iframe/14041297#14041297 and https://stackoverflow.com/questions/15273042/catch-error-if-iframe-src-fails-to-load-error-refused-to-display-http-ww/18665488#18665488 – sideshowbarker Jul 07 '17 at 09:38
  • Thanks. Most relevant from that first question, "If it's not the same domain and you don't have control of the iframe, there's no way for the outer document to know what's going on inside it because of security constraints." Now the question is, what's the least-worst way to handle this from the user's perspective? – Coderer Jul 07 '17 at 09:51

0 Answers0