“访问被拒绝”尝试访问以编程方式创建的
我有一个项目,需要在其中创建一个
我没有设置
我可以正常工作,但有一个严重的例外 - 如果在父页面(可能在部署此小部件的某些环境中)、Internet Explorer(可能是所有版本,但我已经)中设置了 document.domain 属性在 6、7 和 8 中确认)当我尝试访问此
这是有道理的,因为我知道 Internet Explorer 要求您将所有相互通信的窗口/框架的 document.domain 设置为相同的值。但是,我不知道有什么方法可以在我无法访问的文档上设置此值。
有谁知道如何做到这一点 - 以某种方式设置此动态创建的
这是我的测试代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Document.domain Test</title>
<script type="text/javascript">
document.domain = 'onespot.com'; // set the page's document.domain
</script>
</head>
<body>
<p>This is a paragraph above the <iframe>.</p>
<div id="placeholder"></div>
<p>This is a paragraph below the <iframe>.</p>
<script type="text/javascript">
var iframe = document.createElement('iframe'), doc; // create <iframe> element
document.getElementById('placeholder').appendChild(iframe); // append <iframe> element to the placeholder element
setTimeout(function() { // set a timeout to give browsers a chance to recognize the <iframe>
doc = iframe.contentWindow || iframe.contentDocument; // get a handle on the <iframe> document
alert(doc);
if (doc.document) { // HEREIN LIES THE PROBLEM
doc = doc.document;
}
doc.body.innerHTML = '<h1>Hello!</h1>'; // add an element
}, 10);
</script>
</body>
</html>
我将其托管在:
http://troy.onespot.com/static /access_denied.html
正如您在 IE 中加载此页面时所看到的,在我调用alert() 时,我确实拥有
非常感谢您的任何帮助或建议!我将感谢任何能帮助我找到解决方案的人。
I have project in which I need to create an <iframe> element using JavaScript and append it to the DOM. After that, I need to insert some content into the <iframe>. It's a widget that will be embedded in third-party websites.
I don't set the "src" attribute of the <iframe> since I don't want to load a page; rather, it is used to isolate/sandbox the content that I insert into it so that I don't run into CSS or JavaScript conflicts with the parent page. I'm using JSONP to load some HTML content from a server and insert it in this <iframe>.
I have this working fine, with one serious exception - if the document.domain property is set in the parent page (which it may be in certain environments in which this widget is deployed), Internet Explorer (probably all versions, but I've confirmed in 6, 7, and 8) gives me an "Access is denied" error when I try to access the document object of this <iframe> I've created. It doesn't happen in any other browsers I've tested in (all major modern ones).
This makes some sense, since I'm aware that Internet Explorer requires you to set the document.domain of all windows/frames that will communicate with each other to the same value. However, I'm not aware of any way to set this value on a document that I can't access.
Is anyone aware of a way to do this - somehow set the document.domain property of this dynamically created <iframe>? Or am I not looking at it from the right angle - is there another way to achieve what I'm going for without running into this problem? I do need to use an <iframe> in any case, as the isolated/sandboxed window is crucial to the functionality of this widget.
Here's my test code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Document.domain Test</title>
<script type="text/javascript">
document.domain = 'onespot.com'; // set the page's document.domain
</script>
</head>
<body>
<p>This is a paragraph above the <iframe>.</p>
<div id="placeholder"></div>
<p>This is a paragraph below the <iframe>.</p>
<script type="text/javascript">
var iframe = document.createElement('iframe'), doc; // create <iframe> element
document.getElementById('placeholder').appendChild(iframe); // append <iframe> element to the placeholder element
setTimeout(function() { // set a timeout to give browsers a chance to recognize the <iframe>
doc = iframe.contentWindow || iframe.contentDocument; // get a handle on the <iframe> document
alert(doc);
if (doc.document) { // HEREIN LIES THE PROBLEM
doc = doc.document;
}
doc.body.innerHTML = '<h1>Hello!</h1>'; // add an element
}, 10);
</script>
</body>
</html>
I've hosted it at:
http://troy.onespot.com/static/access_denied.html
As you'll see if you load this page in IE, at the point that I call alert(), I do have a handle on the window object of the <iframe>; I just can't get any deeper, into its document object.
Thanks very much for any help or suggestions! I'll be indebted to whomever can help me find a solution to this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
提示。是的,这是一个 IE 问题(bug?很难说,因为没有针对这种不愉快的记录标准)。当您创建 srcless iframe 时,它会从父文档的
location.host
而不是其document.domain
接收document.domain
。到那时你就已经输了,因为你无法改变它。一个可怕的解决方法是将
src
设置为 javascript: URL(呃!):但由于某种原因,这样的文档无法从脚本设置自己的
document.domain
在 IE 中(好老的“未指定错误”),所以你不能用它来重新建立父级(*)之间的桥梁。您可以使用它来编写整个文档 HTML,假设该小部件在实例化后不需要与其父文档通信。然而,iframe JavaScript URL 在 Safari 中不起作用,因此您仍然需要某种浏览器嗅探来选择使用哪种方法。
*:由于某些其他原因,您可以在 IE 中从第二个文档设置
document.domain
,document.writing 由第一个文档设置。所以这是有效的:在这一点上,丑陋程度对我来说太高了,我出去了。我会像 David 说的那样做外部 HTML。
Sigh. Yeah, it's an IE issue (bug? difficult to say as there is no documented standard for this kind of unpleasantness). When you create a srcless iframe it receives a
document.domain
from the parent document'slocation.host
instead of itsdocument.domain
. At that point you've pretty much lost as you can't change it.A horrendous workaround is to set
src
to a javascript: URL (urgh!):But for some reason, such a document is unable to set its own
document.domain
from script in IE (good old “unspecified error”), so you can't use that to regain a bridge between the parent(*). You could use it to write the whole document HTML, assuming the widget doesn't need to talk to its parent document once it's instantiated.However iframe JavaScript URLs don't work in Safari, so you'd still need some kind of browser-sniffing to choose which method to use.
*: For some other reason, you can, in IE, set
document.domain
from a second document, document.written by the first document. So this works:At this point the hideousness level is too high for me, I'm out. I'd do the external HTML like David said.
是的,访问异常是由于
document.domain
必须在您的父级和 iframe 中匹配,在它们匹配之前,您将无法以编程方式设置document iframe 的 .domain
属性。我认为您最好的选择是将页面指向您自己的模板:
在 myiframe.htm 中:
Well yes, the access exception is due to the fact that
document.domain
must match in your parent and your iframe, and before they do, you won't be able to programmatically set thedocument.domain
property of your iframe.I think your best option here is to point the page to a template of your own:
And in myiframe.htm:
好吧,我实际上有一个非常相似的问题,但有一个转折......
假设顶级站点是 a.foo.com - 现在我将文档域设置为 a.foo.com,
然后在我创建/拥有的 iframe 中,我也将其设置为 a.foo.com
请注意,我也无法设置它们foo.com b/c 页面中还有另一个 iframe 指向 bafoo.com(它再次使用 a.foo.com,但我无法更改那里的脚本代码)
您会注意到,我基本上将 document.domain 设置为它已经会的内容无论如何...但是我必须这样做才能访问我
在框架内从 bafoo.com 提到的其他 iframe,在我设置域之后,即使所有 iframe 都具有相同的设置,但在进入IE 6/7 中的父级
还有其他一些非常奇怪的事情
在外部/顶层 ,如果我等待它的 onload 事件,并设置一个计时器,最终我可以到达我需要访问的框架......但我永远无法从下往上到达......
我真的需要能够做到
如果我将所有内容设置为 foo.com (正如我所说,我不能这样做), 这一点,它可以工作!
但由于某种原因,当使用与 location.host 相同的值时......它没有,而且它吓死我了......
well i actually have a very similar problem, but with a twist...
say the top level site is a.foo.com - now i set document domain to a.foo.com
then in the iframe that i create / own,i also set it too a.foo.com
note that i cant set them too foo.com b/c there is another iframe in the page pointed to b.a.foo.com (which again uses a.foo.com but i cant change the script code there)
youll note that im essentially setting document.domain to what it already would be anyway...but i have to do that to access the other iframe i mentioned from b.a.foo.com
inside my frame, after i set the domain, eventhough all iframes have the same setting, i still get an error when reaching up into the parent in IE 6/7
there are other things that r really bizaree
in the outside / top level, if i wait for its onload event, and set a timer, eventually i can reach down into the frame i need to access....but i can never reach from bottom up...
and i really need to be able to
also if i set everything to be foo.com (which as i said i cannot do) IT WORKS!
but for some reason, when using the same value as location.host....it doesnt and its freaking killing me.....
我只是使用
并且工作正常。I just use
<iframe src="about:blank" ...></iframe>
and it works fine.对于 IE 来说,端口很重要。在域之间,它应该是相同的端口。
for IE, the port matters. In between domains, it should be same port.
您是否尝试过 jQuery.contents() ?
Have you tried jQuery.contents() ?
当您尝试通过 document.frames 对象访问 iframe 时,IE 的问题似乎就出现了 - 如果您将创建的 iframe 的引用存储在变量中,那么您可以通过变量访问注入的 iframe (下面代码中的 my_iframe )。
我已经让它在 IE6/7/8 中工作
It seems that the problem with IE comes when you try and access the iframe via the document.frames object - if you store a reference to the created iframe in a variable then you can access the injected iframe via the variable (my_iframe in the code below).
I've gotten this to work in IE6/7/8
我有一个类似的问题,我的解决方案是这个代码片段(在 IE8/9、Chrome 和 Firefox 中测试)
我尝试了几种方法,但这个似乎是最好的。您可以在此处我的博客文章中找到一些解释。
I had a similar issue and my solution was this code snippet (tested in IE8/9, Chrome and Firefox)
I've tried several methods but this one appeared to be the best. You can find some explanations in my blog post here.
按照 Andralor 的极其简单的方法解决了我的问题: https://github.com/fancyapps /fancyBox/issues/766
本质上,再次调用 iframe onUpdate:
Following the exceedingly simple method from Andralor here fixed the issue for me: https://github.com/fancyapps/fancyBox/issues/766
Essentially, call the iframe again onUpdate:
在父页面中设置
document.domain
属性是不够的。 父级和子级必须使用相同的 https/http 协议。另外,端口必须相同(如另一个答案中所述)。因此,例如,如果您导航到
http://subdomain1.yoursite.com/parent.htm
并且子 iframe 是从
httpS://subdomain2.yoursite.com/child.htm
那么从孩子到父母的访问将被拒绝。
Setting the
document.domain
property in the parent page isn't enough. Both the parent and child must use the same https/http protocol. Also, the port must be the same (as mentioned here in another answer).So, for example if you navigate to
http://subdomain1.yoursite.com/parent.htm
and the child iframe is loaded from
httpS://subdomain2.yoursite.com/child.htm
then access will be denied from child to parent.
IE 与所有其他浏览器一样使用 iframe(至少对于主要功能)。您只需要保留一组规则:
当所有iframe资源加载完毕后,将document.domain更改为与parent中定义的相同。 (稍后需要执行此操作,因为设置domain会导致iframe资源请求失败)
现在您可以为父窗口创建引用:var winn = window.parent
varparentContent = $('html', winn.document)
IE works with iframe like all the other browsers (at least for main functions). You just have to keep a set of rules:
when all iframe resources are loaded, change document.domain to be the same as the one defined in parent. (You need to do this later because setting domain will cause the iframe resource's request to fail)
now you can make a reference for parent window: var winn = window.parent
var parentContent = $('html', winn.document)
对我来说,我发现更好的答案是检查访问被拒绝的文件权限。
我刚刚更新到 jQuery-1.8.0.js,并在 IE9 中收到“访问被拒绝”错误。
在 Windows 资源管理器中,
测试了该网站。
没有更多的问题了。
我也必须对刚刚更新的 jQuery-UI 脚本执行相同的操作
For me I found the better answer was to check the file permissons that access is being denied to.
I just update to jQuery-1.8.0.js and was getting the Access Denied error in IE9.
From Windows Explorer
Tested the site.
No more issue.
I had to do the same for the the jQuery-UI script I had just updated as well