[javascript] 프로그래밍 방식으로 생성 된 <iframe>의 문서 개체에 액세스하려고 할 때 “액세스가 거부되었습니다.”JavaScript 오류 (IE 전용)

JavaScript를 사용하여 <iframe> 요소를 만들고 DOM에 추가해야하는 프로젝트가 있습니다. 그런 다음 <iframe>에 콘텐츠를 삽입해야합니다. 제 3 자 웹 사이트에 삽입 될 위젯입니다.

페이지를로드하고 싶지 않기 때문에 <iframe>의 “src”속성을 설정하지 않았습니다. 오히려 CSS 또는 JavaScript가 상위 페이지와 충돌하지 않도록 삽입하는 콘텐츠를 격리 / 샌드 박스하는 데 사용됩니다. JSONP를 사용하여 서버에서 일부 HTML 콘텐츠를로드하고이 <iframe>에 삽입합니다.

한 가지 심각한 예외를 제외하고 잘 작동합니다. 6, 7, 8에서 확인) 내가 만든이 <iframe>의 문서 개체에 액세스하려고하면 “액세스가 거부되었습니다.”오류가 발생합니다. 내가 테스트 한 다른 브라우저 (모든 주요 최신 브라우저)에서는 발생하지 않습니다.

Internet Explorer에서 서로 통신 할 모든 창 / 프레임의 document.domain을 동일한 값으로 설정해야한다는 것을 알고 있기 때문에 이것은 어느 정도 의미가 있습니다. 그러나 액세스 할 수없는 문서에이 값을 설정하는 방법을 모릅니다.

이 작업을 수행하는 방법을 알고있는 사람이 있습니까?-어떻게 든 동적으로 생성 된 <iframe>의 document.domain 속성을 설정합니까? 아니면 나는 그것을 직각으로 보지 않고 있습니까?이 문제에 부딪히지 않고 내가 원하는 것을 달성하는 다른 방법이 있습니까? 격리 / 샌드 박스 창은이 위젯의 ​​기능에 중요하기 때문에 어떤 경우에도 <iframe>을 사용해야합니다.

내 테스트 코드는 다음과 같습니다.

<!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>의 창 개체에 대한 핸들이 있습니다. 문서 객체에 대해 더 깊이 이해할 수 없습니다.

도움이나 제안에 감사드립니다! 나는 이것에 대한 해결책을 찾는 데 도움을 줄 수있는 사람에게 빚을 질 것이다.



답변

document.domain 속성이 부모 페이지에 설정되어 있으면 Internet Explorer에서 “액세스가 거부되었습니다.”라는 메시지가 표시됩니다.

한숨. 네, 이것은 IE 문제입니다 (버그? 이런 종류의 불쾌함에 대한 문서화 된 표준이 없기 때문에 말하기 어렵습니다). 당신이 srcless은 iframe을 만들 때 그것은 수신 document.domain부모 문서에서는의 location.host대신으로 document.domain. 그 시점에서 당신은 그것을 바꿀 수 없기 때문에 거의 잃었습니다.

끔찍한 해결 방법은 srcjavascript : URL (urgh!)로 설정하는 것입니다.

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

그러나 어떤 이유로 이러한 문서는 document.domainIE의 스크립트에서 자체적으로 설정할 수 없으므로 (오래된 “지정되지 않은 오류”)이를 사용하여 부모 (*) 사이의 다리를 다시 얻을 수 없습니다. 당신은 할 수 인스턴스화 된 후에는 부모 문서에 이야기 할 필요가 없습니다 위젯을 가정, 전체 문서의 HTML을 작성하는 데 사용합니다.

그러나 iframe JavaScript URL은 Safari에서 작동하지 않으므로 사용할 방법을 선택하려면 여전히 일종의 브라우저 스니핑이 필요합니다.

* : 다른 이유로 IE에서는 첫 번째 문서에 의해 작성된 두 번째 문서 인 document.에서 설정할 수 있습니다document.domain . 그래서 이것은 작동합니다.

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

이 시점에서 끔찍함 수준이 너무 높아서 나갑니다. 나는 David가 말한 것처럼 외부 HTML을 할 것입니다.


답변

예, 액세스 예외는 document.domain부모와 iframe에서 일치해야 한다는 사실 때문이며, 일치하기 전에 iframe의 document.domain속성 을 프로그래밍 방식으로 설정할 수 없습니다 .

여기에서 가장 좋은 방법은 페이지를 자신의 템플릿으로 지정하는 것입니다.

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

그리고 myiframe.htm에서 :

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


답변

글쎄, 나는 실제로 매우 비슷한 문제가 있지만 비틀어 … 최상위 사이트가 a.foo.com이라고 말하십시오-이제 문서 도메인을 a.foo.com으로 설정했습니다.

그런 다음 내가 생성 / 소유 한 iframe에서 a.foo.com도 설정했습니다.

내가 너무 foo.com을 설정할 수 없다는 점에 유의하십시오 .b / c 페이지에 bafoo.com을 가리키는 다른 iframe이 있습니다 (다시 a.foo.com을 사용하지만 스크립트 코드를 변경할 수 없습니다)

당신은 본질적으로 document.domain을 어쨌든 이미 설정 한 것으로 설정한다는 것을 알 수 있습니다 …하지만 bafoo.com에서 언급 한 다른 iframe에 액세스하려면 그렇게해야합니다.

내 프레임 내에서 도메인을 설정 한 후 모든 iframe이 동일한 설정을 갖더라도 IE 6/7에서 부모에 도달 할 때 여전히 오류가 발생합니다.

r 정말 비 자리 다른 것들이 있습니다

외부 / 최상위 수준에서 onload 이벤트를 기다렸다가 타이머를 설정하면 결국 액세스해야하는 프레임에 도달 할 수 있습니다 ….하지만 아래에서 위로 도달 할 수는 없습니다. 할 수 있어야

또한 모든 것을 foo.com으로 설정하면 (내가 말한대로 할 수 없습니다) 작동합니다! 그러나 어떤 이유로, location.host와 같은 값을 사용할 때 …. 그것은 나를 죽이는 것입니다 …..


답변

나는 단지 사용 <iframe src="about:blank" ...></iframe>하고 잘 작동합니다.


답변

IE의 경우 포트가 중요합니다. 도메인 간에는 동일한 포트 여야합니다.


답변

jQuery.contents () 사용해 보셨습니까 ?


답변

IE의 문제는 document.frames 객체를 통해 iframe에 액세스하려고 할 때 발생하는 것 같습니다. 생성 된 iframe에 대한 참조를 변수에 저장하면 변수 (아래 코드에서 my_iframe)를 통해 삽입 된 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);
}