Executing try/catch on different Window in IE
Consider a page containing an iframe. The iframe's content might look like this
<script type="text/javascript">
window.foo = function () {
nonExisting();
};
window.bar = function () {
throw "An error!";
};
</script>
Now, I wanna execute something like this:
try {
iframe.contentWindow.foo();
} catch (e) { console.log('ok'); }
and
try {
iframe.contentWindow.bar();
} ca开发者_JS百科tch (e) { console.log('ok'); }
This is what I get:
- Chrome/Firefox/Opera - 'ok', 'ok' (expected behaviour)
- IE8 - "Object expected" error, Uncaught Exception
WTF is going on here? How could that be an uncaught exception when I'm using a try/catch block? Is that a bug? Or does anything in the specs allow this behaviour?
And most importantly: Can I make it work as it should?That's because you have a typo: "An error"!
.
If I run it without that typo on IE9 with IE8 emulated, it works: http://jsfiddle.net/vsSgE/3/.
I ran into this exact issue today. I had defined a couple of "exception classes" in the parent window, which I "imported" into the child window (iframe) to be able to handle them with instanceof
in the parent. Something like this:
Parent window
window.MyExceptions = {
RenderingException: function () { ... }
// ...more exception types
};
// Somewhere further down in the code, assuming 'iframe' is the child iframe
try {
iframe.contentWindow.renderAllTheThings();
} catch (ex) {
if (ex instanceof MyExceptions.RenderingException) {
// ...
}
}
Child (iframe) window
window.MyExceptions = window.parent.MyExceptions; // Import exception types
window.renderAllTheThings = function () {
// ...
throw new MyExceptions.RenderingException();
};
Using this setup, I got the same problem as you did - it worked in all modern browsers I tested, but failed in IE8 with the "uncaught exception" error.
My workaround was to add a simple utility function to the MyExceptions object in the parent window that does the actual throwing, like this:
window.MyExceptions = {
RenderingException: function () { ... },
// ...more exception types
Throw: function (ex) {
throw ex;
}
};
Then whenever I wanted to throw an exception from the child window to be handled in the parent, I would do MyExceptions.Throw(new MyExceptions.RenderingException());
.
Not exactly elegant, but I needed to get it working.
精彩评论