开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜