IE9“权限被拒绝”在一个由不存在的框架创建的XML文档上

3
我是一名有用的助手,会进行文本翻译。
我遇到了一个非常奇怪的情况。以下是我的设置:
父窗口拥有一个名为“bar”的对象,其中包含一个XML文档和几个其他属性:
<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>

第一个子框架通过ajax加载一个简单的xml文件:

<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>

这个 XML 是:

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

在成功时,它会在父窗口中创建一个“bar”实例,并将其存储在“foo”变量中,该变量再次驻留在父窗口中。
然后它(成功地)输出这些属性并重定向到第二个子框架。
第二个子框架尝试访问父框架中的“foo”对象,并输出其属性:
<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>

现在有趣的事情发生了:在FF和Chrome中,我们看到3个属性在_child1和_child2中分别触发两次。然而,在IE9中,我们只看到5个警报!
原因是parent.foo.doc由于某种原因引发“权限被拒绝”。
我认为原因是IE“记住”xml文档是在第一个子框架中创建的(可能出于性能原因),当第二个子框架尝试访问该对象时,IE无法找到它(或将其存储在受限制的内存堆栈中)。
此外,当我尝试这种情况而没有重定向-只是将那两个子帧放在父帧中一起时-第二个子帧没有问题访问父级的xml文档。
一种解决方法是在“父级”内部分配之前克隆这些xml文档,但我们有许多这样的场景,首先我想问是否有更好的想法?
谢谢。
2个回答

2

如果在另一个页面中分配了JavaScript对象,并进行了垃圾回收,那么Internet Explorer绝对不会允许您继续使用该对象。您可以传递原始值,但我曾经遇到过“Date”实例在帧之间传递时出现问题(虽然这是很久以前的事情)。

一个技巧是调用父页面中的函数,从原始值创建您的对象:

// in parent:

function newBar(what, ever) {
  return new bar(what, ever);
}

// in the frame page:

parent.foo = parent.newBar("what", "ever");

我认为这样可以避免问题,因为对象将使用父页面中的Object构造函数进行分配,而不是在框架页面中进行分配。在以前的工作中,我所涉及的应用程序是一个庞大的、分散的东西,涉及到无数个iframe(用于对话框、警告等各种东西)。我经常遇到这个问题,保持清洁足够痛苦,以至于我已经发誓不再使用iframes来处理那种东西。


很奇怪你在旧版本的IE上遇到了这些问题,我们的Web应用程序已经运行了很长时间,只有现在在IE9上才遇到了这个问题。你提出的解决方案听起来不错,但我希望能找到一些全局解决方法。如果你所建议的方法可行,我需要搜索我们所有的代码以查找这种神秘的情况。是的,框架在未来的版本中肯定会被淘汰。 - krulik
另外一件事 - 正如您在我的示例中所看到的,问题仅出现在xml文档实例中,其他属性与父级链接正常。 - krulik
谢谢你的回答!它有效了。虽然我希望有一个对程序员来说更“透明”的解决方案,但我还是接受了它。就像IE9.bug = false; :) 现在因为IE9的缘故,我们需要记住以这种方式创建对象,而且我们团队中的每个新程序员也必须学习这一点。 - krulik

0

只是想分享一种备选解决方案,可以帮助其他人。

由于IE9中iframe对象的新处理方式(在这里说明http://msdn.microsoft.com/en-us/library/gg622929%28v=VS.85%29.aspx?ppud=4),我们的Web应用程序在IE 9中出现了权限被拒绝的问题。

对于我的情况,当iframe(iframe A)中的页面刷新时,存储在页面中的现有值被释放。 当从另一个iframe(iframe B)中进行javascript调用以访问iframe A中的对象时,会出现“权限被拒绝”错误并停止脚本执行。

最后,我使用了javascript try catch来捕获错误,并让脚本继续运行而不是停止执行。

  try {
      var testObj = testObjArray['Object in iframe A'];
  } catch(err) {
      alert(err);
  }

希望这个替代方案能够帮助其他人。 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接