在缩短document.domain后,iframe的contentWindow会抛出访问被拒绝的错误。

10
我会尽力帮您翻译成中文。这段内容是关于动态创建IFRAME的方法。
var wrapUpIframe = document.createElement("iframe");
wrapUpIframe.id = 'WrapUpDialog3';
wrapUpIframe.src = 'WrapUpDialog.html';    
document.body.appendChild(wrapUpIframe);

动态创建后,我的document.domain被缩短为dc.com,而非Servername.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 - Nik Haldimann
@nhaldimann 我使用IE9。 - Dor Cohen
这个问题已经在这里得到了回答:https://dev59.com/7HRC5IYBdhLWcg3wP-dh。 - Bertrand
2
@BertrandLefort 但他说起源是相同的。 - acme
WrapUpDialog3是什么?如何访问contentWindow?如果您能发布一个更完整的示例,那么我们可能能够更好地帮助您。 - Martijn de Milliano
显示剩余3条评论
3个回答

9

首先看一下这个帖子中的正确答案。在我看来,那可能是你的问题所在。

如果不是那样,也许这篇帖子中的快速Hack会有所帮助。

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

不确定这是否相关,但我在网上也发现了这个链接

好的,针对您的评论做出回应。JavaScript函数并不是在分配源,而是设置文档域,这在IE中显然没有正确完成。

查看此链接以获取另一个示例和解释。

因此,我会尝试类似以下的操作...

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>

我还想添加一个链接,讲解一下我以前使用过的显式设置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 Cohen
Dor,你是想在这个HTML页面中加载你在这个问题(http://stackoverflow.com/questions/14849606/load-external-html-file-to-div-and-use-its-js-functions)中提到的js函数吗? - Vic
1
真遗憾我没有得到赏金。 :) - Vic
Dor,如果时间问题是问题所在,请告诉我。 我会编辑我的答案以便其他人也知道。 - Vic

2

你是如何提供文件的?你在地址栏中看到了file:///吗?如果有,请尝试使用web服务器来提供代码。

如果我使用file:///尝试您的代码,Google Chrome将会给出访问被拒绝的错误,但是当它从本地web服务器提供时(即地址以http://localhost/开头),它可以正常工作。


我正在使用普通的HTML页面,没有文件。 - Dor Cohen

1

由于您尚未接受任何答案,可能仍然存在问题。

尝试在两个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。这可以帮助您确定您是否可能正在处理某个特定浏览器的怪癖。


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