【问题标题】:iframe contentWindow throws Access Denied error after shortening document.domainiframe contentWindow 在缩短 document.domain 后抛出拒绝访问错误
【发布时间】:2013-02-06 18:31:05
【问题描述】:

我通过以下方式动态创建 IFRAME:

var wrapUpIframe = document.createElement("iframe");
wrapUpIframe.id = 'WrapUpDialog3';
wrapUpIframe.src = 'WrapUpDialog.html';    
document.body.appendChild(wrapUpIframe);

动态创建后,我的document.domain 将从Servername.dc.com 缩短为仅dc.com

但是当我尝试访问 contentWindow 时,我收到了访问被拒绝错误:

document.getElementById("WrapUpDialog3").contentWindow.SomeFunction();

注意:当我在 HTML 中静态定义 IFRAME 时,它可以正常工作。
我还尝试通过以下方式更改我的 IFRAME document.domain

WrapUpDialog3.document.domain = dc.com;

我检查了document.domain 和我的 IFRAME 域,它们都是相同的。

我能做什么?

我正在使用 IE9。

【问题讨论】:

  • 在什么浏览器中你会得到这种行为?如果我在 Chrome 调试器中输入你的代码,我可以访问 el.contentWindow 很好。请注意,不仅需要匹配域,还需要匹配完整的来源,因此您可以尝试比较两个窗口的document.location.origin
  • @nhaldimann 我使用 IE9
  • 这里已经回答了这个问题:stackoverflow.com/questions/364952/… Bertrand
  • @BertrandLefort 但他说起源是一样的。
  • 什么是WrapUpDialog3?您如何访问contentWindow?如果您可以发布一个更完整的示例,那么我们可能会为您提供更好的帮助。

标签: javascript internet-explorer iframe dynamic access-denied


【解决方案1】:

先看看这个post的正确答案。在我看来,这可能是你的问题。

如果不是这样,那么我从另一个 post 看到的这个快速破解可能会有所帮助。

 var frame = $('<iframe>')
.attr('id', 'myIframe')
.addClass('someClass')
.attr('src', 'javascript:(function () {' +'document.open();document.domain=\'myDomain.net\';document.close();' + '})();');
.appendTo($('#someDiv'));

不确定这是否相关,但我也在网上找到了这个link

好的,所以回复您的评论。 javascript 函数没有分配源,它设置的文档域在 I.E. 中显然没有正确完成

查看此link 以获取另一个示例和说明。

所以我会尝试的可能是这样的......

var wrapUpIframe = document.createElement("iframe");
wrapUpIframe.id = 'WrapUpDialog3';    
wrapUpIframe.src = setSrc();
document.body.appendChild(wrapUpIframe);

function setSrc(){document.open();document.domain=\'dc.com\';document.close();return 'WrapUpDialog.html';}

在运行设置文档域的函数后,您可能需要考虑如何返回 iframe 的实际 url。但据我所知,这可能对你有用。

我有一个类似的问题,但不完全相同的问题,这就是为什么我不能给你一个确切的解决办法。设置文档域的功能让我通过了拒绝访问错误。

您还可以将其添加到您的主文档中,以真正确保域匹配。

 <script type="text/javascript">
    document.domain = 'dc.com';
  </script>

我还想添加一个link 来解释我之前使用过的显式设置 document.domain。这在过去对我很有帮助。特别是这句话...

显式设置该值表示有意与 另一个子域上的脚本(在同一个父域下)。

Dor,您可能遇到了时间问题。我发现了一些我刚刚测试过的代码(这里)对我有用。它确保在您尝试访问 contentWindow 之前加载 iframe。

var iframe = document.createElement("iframe");
iframe.src = "WrapUpDialog.html";

if (iframe.attachEvent){
    iframe.attachEvent("onload", function(){
        alert("Local iframe is now loaded.");
    });
} else {
    iframe.onload = function(){
        alert("Local iframe is now loaded.");
    };
}

document.body.appendChild(iframe);

var iframeWindow = iframe.contentWindow || iframe.contentDocument.parentWindow;

【讨论】:

  • 感谢您的回复,我的src应该是一个外部html页面-WrapUpDialog.html,如何根据您的建议加载它?
  • Dor,你是不是想在这个html页面中加载你在这个问题(stackoverflow.com/questions/14849606/…)中提到的js函数?
  • 很遗憾我没有得到赏金。 :)
  • Dor,如果是时间问题,请告诉我。我将编辑我的答案,以便其他人也知道。
【解决方案2】:

您如何提供文件?您在地址栏中看到file:/// 吗?如果是这样,请尝试使用网络服务器提供您的代码。

如果我使用 file:/// 尝试您的代码,Google Chrome 会出现访问被拒绝错误,但它在从本地网络服务器提供服务时有效(即地址以 http://localhost/ 开头)。

【讨论】:

  • 我使用的是普通的 HTML 页面,没有文件
【解决方案3】:

由于您尚未接受任何给出的答案,您可能仍然有问题。

尝试在两个 HTML 页面中显式设置 document.domain(您似乎只在一个页面中执行此操作)。这意味着正如@Vic 建议的那样,您需要将以下 javascript 代码添加到包含 iframe 的 HTML:

document.domain = 'dc.com';

这意味着您的代码将如下所示:

document.domain = 'dc.com';
var wrapUpIframe = document.createElement("iframe");
wrapUpIframe.id = 'WrapUpDialog3';
wrapUpIframe.src = 'WrapUpDialog.html';    
document.body.appendChild(wrapUpIframe);

然后,在WrapUpDialog.html 本身(不在主页中,因为那样你会绕过安全系统!)你还需要设置document.domain

document.domain = dc.com;

所以你的这条线将不起作用:

WrapUpDialog3.document.domain = 'dc.com';

因为WrapUpDialog.html 本身需要授予其“父”页面执行其javascript 的权限。

此页面上有更多信息:What does document.domain = document.domain do?

最后提示:请使用不同的浏览器尝试您的代码:IE9、Firefox、Google Chrome。这可以帮助您确定您是否正在处理某个特定浏览器的怪癖。

【讨论】:

    猜你喜欢
    • 2015-07-01
    • 1970-01-01
    • 2014-06-20
    • 2012-01-22
    • 2015-01-02
    • 1970-01-01
    • 2014-01-30
    • 2014-09-14
    • 1970-01-01
    相关资源
    最近更新 更多