“访问被拒绝”尝试访问以编程方式创建的

发布于 2024-08-14 12:38:25 字数 2515 浏览 6 评论 0原文

我有一个项目,需要在其中创建一个

我没有设置

我可以正常工作,但有一个严重的例外 - 如果在父页面(可能在部署此小部件的某些环境中)、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 &lt;iframe&gt;.</p>
    <div id="placeholder"></div>
    <p>This is a paragraph below the &lt;iframe&gt;.</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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

顾铮苏瑾 2024-08-21 12:38:25

如果在父页面中设置了 document.domain 属性,Internet Explorer 会显示“访问被拒绝”

提示。是的,这是一个 IE 问题(bug?很难说,因为没有针对这种不愉快的记录标准)。当您创建 srcless iframe 时,它​​会从父文档的 location.host 而不是其 document.domain 接收 document.domain。到那时你就已经输了,因为你无法改变它。

一个可怕的解决方法是将 src 设置为 javascript: URL(呃!):

 iframe.src= "javascript:'<html><body><p>Hello<\/p><script>do things;<\/script>'";

但由于某种原因,这样的文档无法从脚本设置自己的 document.domain在 IE 中(好老的“未指定错误”),所以你不能用它来重新建立父级(*)之间的桥梁。您可以使用它来编写整个文档 HTML,假设该小部件在实例化后不需要与其父文档通信。

然而,iframe JavaScript URL 在 Safari 中不起作用,因此您仍然需要某种浏览器嗅探来选择使用哪种方法。

*:由于某些其他原因,您可以在 IE 中从第二个文档设置 document.domain,document.writing 由第一个文档设置。所以这是有效的:

if (isIE)
    iframe.src= "javascript:'<script>window.onload=function(){document.write(\\'<script>document.domain=\\\""+document.domain+"\\\";<\\\\/script>\\');document.close();};<\/script>'";

在这一点上,丑陋程度对我来说太高了,我出去了。我会像 David 说的那样做外部 HTML。

if the document.domain property is set in the parent page, Internet Explorer gives me an "Access is denied"

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's location.host instead of its document.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!):

 iframe.src= "javascript:'<html><body><p>Hello<\/p><script>do things;<\/script>'";

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:

if (isIE)
    iframe.src= "javascript:'<script>window.onload=function(){document.write(\\'<script>document.domain=\\\""+document.domain+"\\\";<\\\\/script>\\');document.close();};<\/script>'";

At this point the hideousness level is too high for me, I'm out. I'd do the external HTML like David said.

旧时模样 2024-08-21 12:38:25

是的,访问异常是由于 document.domain 必须在您的父级和 iframe 中匹配,在它们匹配之前,您将无法以编程方式设置 document iframe 的 .domain 属性。

我认为您最好的选择是将页面指向您自己的模板:

iframe.src = '/myiframe.htm#' + document.domain;

在 myiframe.htm 中:

document.domain = location.hash.substring(1);

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 the document.domain property of your iframe.

I think your best option here is to point the page to a template of your own:

iframe.src = '/myiframe.htm#' + document.domain;

And in myiframe.htm:

document.domain = location.hash.substring(1);
淡淡離愁欲言轉身 2024-08-21 12:38:25

好吧,我实际上有一个非常相似的问题,但有一个转折......
假设顶级站点是 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.....

长安忆 2024-08-21 12:38:25

我只是使用 并且工作正常。

I just use <iframe src="about:blank" ...></iframe> and it works fine.

一杯敬自由 2024-08-21 12:38:25

对于 IE 来说,端口很重要。在域之间,它应该是相同的端口。

for IE, the port matters. In between domains, it should be same port.

莫多说 2024-08-21 12:38:25

您是否尝试过 jQuery.contents()

Have you tried jQuery.contents() ?

早茶月光 2024-08-21 12:38:25

当您尝试通过 document.frames 对象访问 iframe 时,IE 的问题似乎就出现了 - 如果您将创建的 iframe 的引用存储在变量中,那么您可以通过变量访问注入的 iframe (下面代码中的 my_iframe )。

我已经让它在 IE6/7/8 中工作

var my_iframe;
var iframeId = "my_iframe_name"
if (navigator.userAgent.indexOf('MSIE') !== -1) {
  // IE wants the name attribute of the iframe set
  my_iframe = document.createElement('<iframe name="' + iframeId + '">');
} else {
  my_iframe = document.createElement('iframe');
}

iframe.setAttribute("src", "javascript:void(0);");
iframe.setAttribute("scrolling", "no");
iframe.setAttribute("frameBorder", "0");
iframe.setAttribute("name", iframeId);

var is = iframe.style;
is.border = is.width = is.height = "0px";

if (document.body) {
  document.body.appendChild(my_iframe);
} else {
  document.appendChild(my_iframe);
}

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

var my_iframe;
var iframeId = "my_iframe_name"
if (navigator.userAgent.indexOf('MSIE') !== -1) {
  // IE wants the name attribute of the iframe set
  my_iframe = document.createElement('<iframe name="' + iframeId + '">');
} else {
  my_iframe = document.createElement('iframe');
}

iframe.setAttribute("src", "javascript:void(0);");
iframe.setAttribute("scrolling", "no");
iframe.setAttribute("frameBorder", "0");
iframe.setAttribute("name", iframeId);

var is = iframe.style;
is.border = is.width = is.height = "0px";

if (document.body) {
  document.body.appendChild(my_iframe);
} else {
  document.appendChild(my_iframe);
}
他是夢罘是命 2024-08-21 12:38:25

我有一个类似的问题,我的解决方案是这个代码片段(在 IE8/9、Chrome 和 Firefox 中测试)

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);

iframe.src = 'javascript:void((function(){var script = document.createElement(\'script\');' +
  'script.innerHTML = "(function() {' +
  'document.open();document.domain=\'' + document.domain +
  '\';document.close();})();";' +
  'document.write("<head>" + script.outerHTML + "</head><body></body>");})())';

iframe.contentWindow.document.write('<div>foo</div>');

我尝试了几种方法,但这个似乎是最好的。您可以在此处我的博客文章中找到一些解释。

I had a similar issue and my solution was this code snippet (tested in IE8/9, Chrome and Firefox)

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);

iframe.src = 'javascript:void((function(){var script = document.createElement(\'script\');' +
  'script.innerHTML = "(function() {' +
  'document.open();document.domain=\'' + document.domain +
  '\';document.close();})();";' +
  'document.write("<head>" + script.outerHTML + "</head><body></body>");})())';

iframe.contentWindow.document.write('<div>foo</div>');

I've tried several methods but this one appeared to be the best. You can find some explanations in my blog post here.

睫毛上残留的泪 2024-08-21 12:38:25

按照 Andralor 的极其简单的方法解决了我的问题: https://github.com/fancyapps /fancyBox/issues/766

本质上,再次调用 iframe onUpdate:

$('a.js-fancybox-iframe').fancybox({
    type: 'iframe',
    scrolling : 'visible',
    autoHeight: true,
    onUpdate: function(){
     $("iframe.fancybox-iframe");
   }
 });

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:

$('a.js-fancybox-iframe').fancybox({
    type: 'iframe',
    scrolling : 'visible',
    autoHeight: true,
    onUpdate: function(){
     $("iframe.fancybox-iframe");
   }
 });
走走停停 2024-08-21 12:38:25

在父页面中设置 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.

初懵 2024-08-21 12:38:25

IE 与所有其他浏览器一样使用 iframe(至少对于主要功能)。您只需要保留一组规则:

  • 在 iframe 中加载任何 javascript 之前(js 中需要了解 iframe 父级的部分),请确保父级已更改 document.domain。
  • 当所有iframe资源加载完毕后,将document.domain更改为与parent中定义的相同。 (稍后需要执行此操作,因为设置domain会导致iframe资源请求失败)

  • 现在您可以为父窗口创建引用:var winn = window.parent

  • 现在您可以引用父 HTML,以便操作它:
    varparentContent = $('html', winn.document)
  • 此时您应该可以访问 IE 父窗口/文档,并且您可以像您不想的那样更改它

IE works with iframe like all the other browsers (at least for main functions). You just have to keep a set of rules:

  • before you load any javascript in the iframe (that part of js which needs to know about the iframe parent), ensure that the parent has document.domain changed.
  • 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

  • now you can make a reference to parent HTML, in order to manipulate it:
    var parentContent = $('html', winn.document)
  • at this point you should have access to IE parent window/document and you can change it as you wont
入怼 2024-08-21 12:38:25

对我来说,我发现更好的答案是检查访问被拒绝的文件权限。

我刚刚更新到 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

  • I right clicked on the file selected the Properties
  • Selected the Security Tab
  • Clicked the Advanced Button
  • Selected the Owner Tab
  • Clicked on Edit Button
  • Selected Administrators(MachineName\Administrators)
  • Clicked Apply
  • Closed all the windows.

Tested the site.
No more issue.

I had to do the same for the the jQuery-UI script I had just updated as well

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文