“访问被拒绝"尝试访问以编程方式创建的 <iframe> 的文档对象时出现 JavaScript 错误(仅限 IE) [英] "Access is denied" JavaScript error when trying to access the document object of a programmatically-created <iframe> (IE-only)

查看:18
本文介绍了“访问被拒绝"尝试访问以编程方式创建的 <iframe> 的文档对象时出现 JavaScript 错误(仅限 IE)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个项目需要在其中创建一个 <iframe>元素使用 JavaScript 并将其附加到 DOM.之后,我需要在 <iframe> 中插入一些内容.这是一个将嵌入第三方网站的小部件.

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.

我没有设置 <iframe> 的src"属性.因为我不想加载页面;相反,它用于隔离/沙箱我插入的内容,这样我就不会遇到与父页面的 CSS 或 JavaScript 冲突.我正在使用 JSONP 从服务器加载一些 HTML 内容并将其插入到这个 <iframe>.

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>.

我的这个工作正常,有一个严重的例外 - 如果 document.domain 属性设置在父页面(它可能在部署此小部件的某些环境中)、Internet Explorer(可能所有版本,但我已在 6、7 和 8 中确认)当我尝试访问此 <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).

这是有道理的,因为我知道 Internet Explorer 要求您将所有将相互通信的窗口/框架的 document.domain 设置为相同的值.但是,我不知道有什么方法可以在我无法访问的文档上设置此值.

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.

有没有人知道这样做的方法 - 以某种方式设置这个动态创建的 <iframe> 的 document.domain 属性?或者我不是从正确的角度看它 - 有没有另一种方法可以在不遇到这个问题的情况下实现我的目标?我确实需要使用 <iframe>在任何情况下,因为隔离/沙盒窗口对于此小部件的功能至关重要.

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.

这是我的测试代码:

<!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() 时,我确实在 <iframe> 的窗口对象上有一个句柄;我无法更深入地了解它的文档对象.

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.

推荐答案

如果在父页面中设置了 document.domain 属性,Internet Explorer 会给我一个访问被拒绝"

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

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

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.

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

A horrendous workaround is to set src to a javascript: URL (urgh!):

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

但是由于某种原因,这样的文档无法从 IE 中的脚本设置自己的 document.domain(好老的未指定错误"),因此您不能使用它来重新获得父母(*)之间的桥梁.您可以使用它来编写整个文档 HTML,假设小部件在实例化后不需要与其父文档对话.

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.

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

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.

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

*: 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>'";

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

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

这篇关于“访问被拒绝"尝试访问以编程方式创建的 &lt;iframe&gt; 的文档对象时出现 JavaScript 错误(仅限 IE)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆