javascript iframe contentWindow 在缩短 document.domain 后抛出拒绝访问错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15002168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 23:06:29  来源:igfitidea点击:

iframe contentWindow throws Access Denied error after shortening document.domain

javascriptinternet-exploreriframedynamicaccess-denied

提问by Dor Cohen

I create an IFRAME dynamically in the following way:

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

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

after the dynamic creation my document.domainis being shortened from Servername.dc.comto only dc.com,

动态创建后 mydocument.domain被缩短Servername.dc.com为 only dc.com

but when I try to access contentWindowI got an Access is denied error:

但是当我尝试访问时,contentWindow出现访问被拒绝错误:

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

Note:When I define the IFRAME statically in the HTML it works fine.
I also tried to change my IFRAME document.domainin the following way:

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

WrapUpDialog3.document.domain = dc.com;

I checked both document.domainand my IFRAME domain and they are both identical.

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

What can I do?

我能做什么?

I'm working with IE9.

我正在使用 IE9。

采纳答案by Vic

First take a look at the correct answer from this post. It looks to me like that could be your issue.

首先看看这篇文章的正确答案。在我看来,这可能是您的问题。

If not that then maybe this quick hack I saw from another postmight help.

如果不是这样,那么我从另一篇文章中看到的这个快速黑客可能会有所帮助。

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

Not sure if this is relevant but I also found this on the web link.

不确定这是否相关,但我也在网络链接上找到了这个。

OK, so to respond to your comment. The javascript function isn't assigning the source, it's setting the document domain which apparently doesn't get done correctly in I.E.

好的,所以来回应你的评论。javascript 函数没有分配源,它设置的文档域在 IE 中显然没有正确完成

Check out this linkfor another example and explanation.

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

So what I would try might be something like this ...

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

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';}

You might have to play around with how to return the actual url for the iframe after running the function that sets the document domain. But from what I am seeing this might work for you.

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

I had a similar issue but not exactly the same problem which is why I can't give you an exact fix. The function setting the document domain was what got me past the access denied error.

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

You could also add this to your main document to really make sure the domains match.

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

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

I also wanted to add a linkfor some explanation on explicitly setting the document.domain that I had used before. This was helpful to me in the past. Particularly this quote ...

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

Explicitly setting the value indicates intent to "cooperate" with a script on another subdomain (under the same parent domain).

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

Dor, you may be having a timing issue. I found some code (here) that I just tested that works for me. It makes sure that the iframe is loaded before you try to access the contentWindow.

多尔,你可能有时间问题。我发现了一些我刚刚测试过的代码(这里)对我有用。它确保在您尝试访问 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;

回答by Martijn de Milliano

How do you serve your files? Do you see file:///in your address bar? If so, try serving your code using a webserver.

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

Google Chrome gives an access denied error if I try your code using file:///, but it works when served from a local webserver (i.e. the address starts with http://localhost/).

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

回答by Martijn de Milliano

Since you have not yet accepted any of the answers given you probably still have the problem.

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

Try setting document.domainexplicitly in both HTML pages (you seem to be doing this in one page only). This means that as @Vic suggested, you need to add the following javascript code to the HTML that includes the iframe:

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

document.domain = 'dc.com';

This means that your code would look like this:

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

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

Then, in WrapUpDialog.htmlitself (not in the main page because then you would circumvent the security system!) you need to set document.domainas well:

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

document.domain = dc.com;

So this line of yours will NOT work:

所以你的这行行不通:

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

because WrapUpDialog.htmlitself needs to grant permission to its "parent" page to execute its javascript.

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

There is more info on this page: What does document.domain = document.domain do?.

此页面上有更多信息:document.domain = document.domain 有什么作用?.

Final hint: do try your code using different browsers: IE9, Firefox, Google Chrome. This can help you identify whether you are perhaps dealing with a quirk of one particular browser.

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