Search code examples
javascriptinternet-explorer-9framesxmldocumentpermission-denied

IE9 "permission denied" on an xml document which was created by a frame which no longer exist


I came into a really strange situation. I have the following setup:

Parent window has an object "bar" which includes an xml document and few other properties:

<html>
<head>
<script type="text/javascript">
var foo=null; //used in most report pages
var bar=function(document, boo){
    this.doc=document;
    this.boo=boo;
    this.baz="serge";
};
</script>
<head>  
<body>
    <iframe src="_child1.html"></iframe>
</body>
</html>

First child frame loads a simple xml file by ajax:

<html>
<head>
<script src="../lib/jquery.min.js"></script>
<script type="text/javascript">
$.ajax({
        url: "books.xml",
        type: "get",
        dataType: "xml",        
        success: function(data) {
            var boo = {
                name: "boo"
            };
            parent.foo = new parent.bar(data, boo);         
            alert(parent.foo.boo.name);
            alert(parent.foo.baz);
            alert(parent.foo.doc.firstChild.nodeName);
            window.location = "_child2.html";
        }
    });
</script>
</head>

<body>
    child1
</body>
</html>

The XML is:

<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
    Vaidyanathan Nagarajan
</bookstore>

On success it creates a "bar" instance in the parent window and stores it in the "foo" variable which again resides in the parent window.

Then it outputs those properties (successfully) and redirects to a second child frame.

Second child frame tries to access the "foo" object in the parent frame and output its properties:

<html>
<head>
<script src="../lib/jquery.min.js"></script>
<script type="text/javascript">
alert(parent.foo.boo.name);
alert(parent.foo.baz);
alert(parent.foo.doc.firstChild.nodeName);
</script>
</head>

<body>
    child2
</body>
</html>

And now the interesting stuff happens: in FF and Chrome we see the 3 properties fire two times: once in _child1 and secondly in _child2. In IE9 however, we see only 5 alerts!

And the reason for this is that parent.foo.doc throws "Permission denied" for some reason.

I believe that the reason is that somehow IE "remembers" that the xml document was created in the first child frame (perhaps for performance reasons) and when the second child frame tries to access that object IE isn't able to find it (or stores it in a restricted memory stack).

Furthermore, when I tried this scenario without redirecting - just putting those two child frames in the parent frame together - the second child frame had no problem accessing the parents' xml doc.

One workaround could be to clone those xml documents inside the "parents" before assigning, but we have many scenarios like this and first I would like to ask whether someone has a better idea?

Thanks.


Solution

  • Internet Explorer will absolutely not let you get away with using a JavaScript object allocated in a separate page once that separate page has been garbage-collected. You can pass primitive values, but I've had problems (a long long time ago, but still) with "Date" instances passed between frames.

    A trick you can pull is to call a function in the parent page to create your object from primitive values:

    // in parent:
    
    function newBar(what, ever) {
      return new bar(what, ever);
    }
    
    // in the frame page:
    
    parent.foo = parent.newBar("what", "ever");
    

    I think that'll insulate you from problems, because the object will be allocated with the Object constructor on the parent page, and not the one in the frame page. In a former life the application I worked on was a vast sprawling thing involving a zillion iframes (for dialogs, warnings, all sorts of stuff). I had this problem all the time, and keeping things clean was painful enough that I've sworn off using iframes for that kind of stuff.