JavaScript에서 부모 Iframe에 액세스하는 방법


170

글쎄, 같은 도메인 페이지를 호출하는 IFrame이 있습니다. 내 문제는 JavaScript라고하는이 페이지 에서이 부모 Iframe의 일부 정보에 액세스하려고한다는 것입니다. 이 Iframe에 어떻게 액세스 할 수 있습니까?

세부 정보 : Windows 환경을 프로그래밍하고 있기 때문에이 페이지와 같은 여러 Iframe이 있으며 동일한 페이지를로드 할 수 있습니다. 이 Iframe을 닫으려고하는데, 그로 인해 내가 어떤 프레임을 닫아야하는지 알아야합니다. 이 Iframe에 대한 참조를 유지하는 배열이 있습니다.

편집 : iframe이 동적으로 생성됩니다


iframe이 동적으로 생성 되더라도 일종의 카운터를 사용하여 새로운 고유 ID를 할당 할 수 있습니다. 결국 ID를 알 필요는 없지만 쉽게 검색 할 수 있습니다. 내 답변을 참조하십시오.
Akash Kava

답변:


138

또한 이름과 ID를 같은 값으로 설정할 수 있습니다

<iframe id="frame1" name="frame1" src="any.html"></iframe>

자식 페이지 내에서 다음 코드를 사용할 수 있습니다.

parent.document.getElementById(window.name);

16
어쩌면 모든 사람에게 분명하지는 않지만이 방법을 사용하면 부모의 라이브러리 객체에 액세스 할 수 있습니다 (부모가 이미 라이브러리를로드 한 경우에만). 예 : parent. $ ( '# something')으로 jQuery에 액세스
Zsolti

1
이 솔루션은 IE5 + 호환성 쿼크 모드와 호환됩니다.
Slayner

2016 년에도 IE가 iframe너무 작은 내용을 인쇄하는 문제에 대한 솔루션의 일부로 훌륭하게 작동합니다 . 그러나 왜 작동합니까? window.name문자열을 반환합니다. window.name작동하지 않는 문자열로 id 이름을 전달하는 것과 다른 점은 무엇입니까 ?)
Karl

3
안녕하세요. Chrome 59에서는 실행되지 않습니다. : VM111 : 1 Uncaught DOMException : 출처가 " xxx "인 프레임이 교차 출처 프레임에 액세스하지 못하도록 차단했습니다 .
Didier68

Chrome은 CORS가 설정되지 않은 경우 교차 출처와 동일한 폴더에있는 파일을 확인합니다. 그들은 보안을위한 것이라고 말합니다. CORS를 설정하려면 서버가 필요합니다. Chrome이 감지되면 사용자에게 서버를 설정하거나 브라우저를 변경하라는 메시지를 표시하십시오.

90

window.frameElement액자 페이지에서 간단히 전화 하십시오. 페이지가 프레임에없는 경우 frameElement가 될 것이다 null.

다른 방법 (프레임 안에 창 요소를 넣는 것은 쉽지 않음)이지만 완전성을 위해 :

/**
 * @param f, iframe or frame element
 * @return Window object inside the given frame
 * @effect will append f to document.body if f not yet part of the DOM
 * @see Window.frameElement
 * @usage myFrame.document = getFramedWindow(myFrame).document;
 */
function getFramedWindow(f)
{
    if(f.parentNode == null)
        f = document.body.appendChild(f);
    var w = (f.contentWindow || f.contentDocument);
    if(w && w.nodeType && w.nodeType==9)
        w = (w.defaultView || w.parentWindow);
    return w;
}

2
감사! IE 6 이상, FF 및 Chrome에서 작동합니다!
rustyx

11
window.frameElementnullwindow와 iframe의 도메인이 다른 경우 (예 : 교차 출처 메시징)를 반환합니다 .
Qwerty

@ Qwerty 솔루션을 찾았습니까?
Ajay Patidar

@AjayPatidar 포기한 것 같아요. :(
Qwerty

78

postMessage API를 사용하는 것이 좋습니다 .

iframe에서 전화 :

window.parent.postMessage({message: 'Hello world'}, 'http://localhost/');

페이지에서 iframe을 포함 시키면 다음과 같은 이벤트를들을 수 있습니다.

window.addEventListener('message', function(event) {
      if(event.origin === 'http://localhost/')
      {
        alert('Received message: ' + event.data.message);
      }
      else
      {
        alert('Origin not allowed!');
      }

    }, false);

그건 그렇고, iframe뿐만 아니라 다른 창으로 전화를 걸 수도 있습니다.

John Resigs 블로그의 postMessage API에 대한 자세한 내용은 여기를 참조하십시오.


7
나는 이것이 가장 좋은 대답이라고 생각합니다. <iframe>내용은 부모에 대해 아무것도 알 필요가 없으며 그 반대도 마찬가지입니다. 그들은 단순한 메시지 계약 만 준수하면됩니다. 대박!
mfeineis 2016 년

1
<iframe>은 여전히 ​​부모의 도메인을 알아야합니다.
Homr Zodyssey 2016 년

1
@HomrZodyssey 부모 도메인은 안전 메커니즘으로 만 사용할 수 있습니다 '*'. 알 수없는 경우 설정할 수 있습니다 .
Amir Ali Akbari

'*'클라이언트에서 사용하십시오 . 다른 모든 솔루션은 서버가 설정되어 있지 않기 때문에 클라이언트 폴더의 파일을 같은 출처가 아닌 것으로 취급하는 Chrome 브라우저에서 오류를 발생시킵니다. 이것은 최선이며 유일한 : 솔루션 dyn-web.com/tutorials/iframes/postmessage

30

오래된 질문이지만 방금 동일한 문제가 발생하여 iframe을 얻는 방법을 찾았습니다. 단순히 부모 창의 frames [] 배열을 반복하고 코드가 실행되는 창에 대해 각 프레임의 contentWindow를 테스트하는 것입니다. 예:

var arrFrames = parent.document.getElementsByTagName("IFRAME");
for (var i = 0; i < arrFrames.length; i++) {
  if (arrFrames[i].contentWindow === window) alert("yay!");
}

또는 jQuery를 사용하여 :

parent.$("iframe").each(function(iel, el) {
  if(el.contentWindow === window) alert("got it");
});

이 방법을 사용하면 각 iframe에 ID를 할당 할 수 있으므로 동적으로 생성되므로 좋습니다. window.parent를 사용하여 iframe 요소를 얻을 수 없으므로 더 직접적인 방법을 찾을 수 없습니다 .iframe 요소를 건너 뛰고 부모 창 요소로 바로 이동합니다. 따라서 ID를 사용하지 않으려는 경우 루프를 통해 유일한 방법으로 보입니다.


1
업데이트 : 이것은 광고 된 것과 똑같이 작동하지 않았으며 contentWindow.document === document를 사용해야했습니다. 왜 그런지 모르겠다. 또한 일부 브라우저에서는 contentDocument를 사용했습니다. 글쎄, 나는 그것을 좋아한다!
Christophe

1
사과, 분명히 Firefox에서만 테스트했습니다. :) 그러나 여러 브라우저에서 jQuery 메소드와 contentWindow를 사용하여 성공했습니다.
component_15939

1
업데이트 : window.frameElement를 사용할 수도 있다는 것을 알았지 만 어떤 브라우저에서 지원하는지 확실하지 않습니다.
Christophe

2
이런 종류의 물건은 더 이상 효과가 없다고 생각합니다. 교차 출처 오류가 발생합니다.
Andrew Mao

@AndrewMao 문제는 동일한 원본 문서에 관한 것이므로 출처 간 문제가 발생할 이유가 없습니다.
Christophe

21

parent부모 페이지에 액세스하는 데 사용할 수 있습니다 . 따라서 함수에 액세스하려면 다음과 같습니다.

var obj = parent.getElementById('foo');

1
케빈, 문제는 ID를 아는 것입니다. Iframe이 여러 개 있는데 내부 코드에서 액세스하고 싶습니다.
José Leal

여전히 교차 출처 프레임에 액세스하여 " 원점" other-localhost : 8000 "인 프레임을 차단했습니다 ."
user2568374

13

iframe의 id가 설정되면 아래와 같이 내부 문서에서 iframe에 액세스 할 수 있습니다.

var iframe = parent.document.getElementById(frameElement.id);

IE, Chrome 및 FF에서 잘 작동합니다.


이것은 복잡한 방법으로 보인다var iframe = frameElement
Oriol

frameElement는 현재 윈도우 컨텍스트에서 객체를 반환하지만 parent.document.getElementById (frameElement.id)는 부모 윈도우 컨텍스트에서 객체를 반환합니다 .frameElement를 사용하여 부모 윈도우의 자바 스크립트 함수를 실행할 수 없습니다. .
Akash Kava

6

어쩌면 그냥 사용

window.parent

전화 프레임 / 창을 얻으려면 iframe에 넣으십시오. 전화 프레임이 여러 개인 경우 사용할 수 있습니다

window.top

3

이것을 시도하십시오. 부모 프레임에서 다음과 같이 IFRAME을 설정하십시오.

<iframe id="frame1" src="inner.html#frame1"></iframe>
<iframe id="frame2" src="inner.html#frame2"></iframe>
<iframe id="frame3" src="inner.html#frame3"></iframe>

각 프레임의 id는 src에서 앵커로 전달됩니다.

그런 다음 내부 HTML에서 location.hash를 통해로드 된 프레임의 ID에 액세스 할 수 있습니다.

<button onclick="alert('I am frame: ' + location.hash.substr(1))">Who Am I?</button>

그런 다음 parent.document.getElementById ()에 액세스하여 iframe 내부에서 iframe 태그에 액세스 할 수 있습니다


예, 이것이 가장 논리적 인 해결책이지만 때로는 iframe의 src를 변경해야합니다.이 해시 또는 GET 매개 변수를 전달하면 각 요청이 좋지 않습니다.
José Leal

매번 해시를 전달하는 것이 왜 나쁜가? 서버가 아닌 브라우저에서만 볼 수 있으며 get 매개 변수처럼 캐싱에 영향을 미치지 않습니다.
Mark Porter

-1
// just in case some one is searching for a solution
function get_parent_frame_dom_element(win)
{
    win = (win || window);
    var parentJQuery = window.parent.jQuery;
    var ifrms = parentJQuery("iframe.upload_iframe");
    for (var i = 0; i < ifrms.length; i++)
    {
        if (ifrms[i].contentDocument === win.document)
            return ifrms[i];
    }
    return null;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.