IFRAME로드가 완료되면 Javascript 콜백?


147

IFRAME로드가 완료되면 콜백을 실행해야합니다. IFRAME의 내용을 제어 할 수 없으므로 콜백을 실행할 수 없습니다.

이 IFRAME은 프로그래밍 방식으로 만들어지며 iframe을 파괴 할뿐만 아니라 콜백에서 변수로 데이터를 전달해야합니다.

어떤 아이디어?

편집하다:

여기 내가 지금 가진 것입니다 :

function xssRequest(url, callback)
{
    var iFrameObj = document.createElement('IFRAME');
    iFrameObj.src = url;            
    document.body.appendChild(iFrameObj);   

    $(iFrameObj).load(function() 
    {
        document.body.removeChild(iFrameObj);
        callback(iFrameObj.innerHTML);
    });
}

iFrame이로드되기 전에 콜백되므로 콜백에 데이터가 반환되지 않습니다.


1
iframe 자체에 이벤트 핸들러를 첨부하고 싶지 않지만 컨텐츠 창입니다.
bobwienholt

1
문제는 도메인 간 요청입니다. iframe이 다른 도메인에서 온 경우이를 수행 할 수 없습니다
Victor

실제로 iframe 객체에로드 이벤트가있어 iframe이 문서로드를 마칠 때마다 발생합니다. 그렇지 않으면 모든로드 후에 창에 연결해야합니다.
Juan Mendes


내 대답을 여기에서보십시오 : stackoverflow.com/a/36155560/3894981
dude

답변:


49

먼저 xssRequest 함수 이름으로 크로스 사이트 요청을 시도하는 것처럼 들립니다. 맞으면 iframe의 내용을 읽을 수 없습니다.

반면에 iframe의 URL이 도메인에 있으면 본문에 액세스 할 수 있지만 시간 초과를 사용하여 iframe을 제거하면 콜백이 정상적으로 작동한다는 것을 알았습니다.

// possibly excessive use of jQuery - but I've got a live working example in production
$('#myUniqueID').load(function () {
  if (typeof callback == 'function') {
    callback($('body', this.contentWindow.document).html());
  }
  setTimeout(function () {$('#frameId').remove();}, 50);
});

4
다음으로 대체 할 수 $('body', this.contentWindow.document).html()있음this.contentDocument.body.outerHTML
Sam Soffes

12
jQuery 없이이 작업을 수행하는 방법을 알고 있습니까?
devios1

6
jQuery 3.0부터는 load사라졌습니다. .on('load', function() { ... })대신 사용하십시오 .
Doppelganger

36

jQuery를 사용하고 있으며 방금 테스트하고 무거운 페이지를로드 할 때 놀랍게도로드되는 것처럼 보이고 iframe로드를 볼 때까지 몇 초 동안 경고가 표시되지 않았습니다.

$('#the_iframe').load(function(){
    alert('loaded!');
});

따라서 jQuery를 사용하지 않으려면 소스 코드를 살펴 보고이 함수가 iframe DOM 요소와 다르게 작동하는지 확인하십시오. 나중에 관심을 가지고 여기에 게시 할 때 직접 살펴 보겠습니다. 또한 최신 크롬에서만 테스트했습니다.


순수한 자바 스크립트로 DOM 요소를 만든 다음 해당 변수를 선택기로 jQuery에 전달했습니다. 아마 코드가 작동하지 않는 이유는 무엇입니까?
Neo

12
jQuery 3.0부터는 load사라졌습니다. .on('load', function() { ... })대신 사용하십시오 .
Doppelganger

8

iframe 태그가 상위 문서의 내용을 둘러싸 지 않기 때문에 iframe의 innerHTML이 비어 있습니다. iframe의 src 속성이 참조하는 페이지에서 컨텐츠를 가져 오려면 iframe의 contentDocument 속성에 액세스해야합니다. src가 다른 도메인에서 온 경우 예외가 발생합니다. 이는 다른 사람의 페이지에서 임의의 JavaScript를 실행하지 못하게하는 사이트 간 스크립팅 취약점을 발생시키는 보안 기능입니다. 다음은 내가 말하는 것을 보여주는 예제 코드입니다.

<script src="http://prototypejs.org/assets/2009/8/31/prototype.js" type="text/javascript"></script>

<h1>Parent</h1>

<script type="text/javascript">
function on_load(iframe) {
  try {
    // Displays the first 50 chars in the innerHTML of the
    // body of the page that the iframe is showing.
    // EDIT 2012-04-17: for wider support, fallback to contentWindow.document
    var doc = iframe.contentDocument || iframe.contentWindow.document;
    alert(doc.body.innerHTML.substring(0, 50));
  } catch (e) {
    // This can happen if the src of the iframe is
    // on another domain
    alert('exception: ' + e);
  }
}
</script>
<iframe id="child" src="iframe_content.html" onload="on_load(this)"></iframe>

추가 예제를 보려면 이것을 iframe의 컨텐츠로 사용하십시오.

<h1>Child</h1>

<a href="http://www.google.com/">Google</a>

<p>Use the preceeding link to change the src of the iframe
to see what happens when the src domain is different from
that of the parent page</p>

1
contentDocument 속성은 IE 7에서 지원되지 않으며 더 많은 IE에서도 지원됩니다. IE를 처리하는 방법은 window [ 'iframeid']. document 또는 개발자
Olga

7

워드 문서 및 PDF와 같은 문서가 iframe으로 스트리밍되고 꽤 잘 작동하는 솔루션을 찾은 경우이 작업을 수행해야했습니다. 핵심은 onreadystatechangediframe 에서 이벤트를 처리하는 것 입니다.

프레임 이름이 "myIframe"이라고 가정하겠습니다. 먼저 코드 시작에서 어딘가에 (iframe 이후에 인라인으로 수행) 이벤트 핸들러를 등록하기 위해 다음과 같은 것을 추가하십시오.

document.getElementById('myIframe').onreadystatechange = MyIframeReadyStateChanged;

iframe에서 onreadystatechage 속성을 사용할 수 없었습니다. 이유를 기억할 수는 없지만 응용 프로그램은 IE 7 및 Safari 3에서 작동해야했기 때문에 그 요인이 될 수 있습니다.

다음은 완전한 상태를 얻는 방법의 예입니다.

function MyIframeReadyStateChanged()
{
    if(document.getElementById('myIframe').readyState == 'complete')
    {
        // Do your complete stuff here.
    }
}

6

i 프레임 내용이 IE에 완전히로드 될 때 대기 스피너 div를 숨기고 싶었습니다. 나는 문자 그대로 Stackoverflow.Com에 언급 된 모든 솔루션을 시도했지만 원하는대로 작동하지 않았습니다.

그런 다음 i 프레임 컨텐츠가 완전히로드되면 $ (Window)로드 이벤트가 시작될 수 있다는 아이디어가있었습니다. 그리고 그것은 정확히 일어난 일입니다. 그래서 나는이 작은 스크립트를 작성하고 마술처럼 일했습니다.

     $(window).load(function () {
     //alert("Done window ready ");
     var lblWait = document.getElementById("lblWait");
     if (lblWait != null ) {
         lblWait.style.visibility = "false";
         document.getElementById("divWait").style.display = "none";
     }
 });

도움이 되었기를 바랍니다.


이것은 간단한 해결책이며 전체 페이지가로드 된 후에 자바 스크립트를 실행하려는 경우 제대로 작동합니다. 즉, 먼저 js 효과없이 완전히로드 된 페이지를 볼 수 있으며 자바 스크립트에 의해 생성 된 변경 사항이 발생할 때마다로드에 따라 1-2 초 후에 발생할 수 있습니다. 나는 개인적으로 iframe 크기를 조정하려고 시도했지만 페이지를 클릭 한 후 처음 3 초 동안 화면에주의를 기울이지 않으면 작동하지만 코드의 패치 워크로 나타날 수 있습니다.
앰퍼샌드

1
귀하의 의견에 감사드립니다.이 솔루션은 페이지가로드 된 후 iframe을로드하기를 원했기 때문에 훌륭한 경우였습니다.
Nada N. Hantouli

2

나는 너와 비슷한 문제가 있었다. 내가 한 것은 jQuery라는 것을 사용한다는 것입니다. 그런 다음 자바 스크립트 코드에서 수행하는 작업은 다음과 같습니다.

$(function(){ //this is regular jQuery code. It waits for the dom to load fully the first time you open the page.

    $("#myIframeId").load(function(){
       callback($("#myIframeId").html());
       $("#myIframeId").remove();

    });

});

HTML을 가져 오기 전에 iFrame을 삭제 한 것처럼 보입니다. 자, 나는 그 문제에 대해 보았습니다 : p

도움이 되었기를 바랍니다 :).


1

내 프로젝트에는 비슷한 코드가있어 정상적으로 작동합니다. 내 코드를 함수에 적용하면 해결책은 다음과 같습니다.

function xssRequest(url, callback)
{
    var iFrameObj = document.createElement('IFRAME');
    iFrameObj.id = 'myUniqueID';
    document.body.appendChild(iFrameObj);       
    iFrameObj.src = url;                        

    $(iFrameObj).load(function() 
    {
        callback(window['myUniqueID'].document.body.innerHTML);
        document.body.removeChild(iFrameObj);
    });
}

어쩌면 내부 HTML이 비어 있거나 (하나 또는 두 가지 원인이 있음) 1. 본문 요소에 사용해야합니다.


1

로드 이벤트가 옳다고 생각합니다. 옳지 않은 것은 iframe 컨텐츠 돔에서 컨텐츠를 검색하는 데 사용하는 방법입니다.

필요한 것은 iframe 객체의 html이 아니라 iframe에로드 된 페이지의 html입니다.

로 콘텐츠 문서에 액세스해야합니다 iFrameObj.contentDocument. 현재 페이지와 동일한 도메인에있는 경우 iframe 내에로드 된 페이지의 DOM을 반환합니다.

iframe을 제거하기 전에 콘텐츠를 검색합니다.

파이어 폭스와 오페라에서 테스트했습니다.

그럼 난 당신이 데이터를 retreive 수 있다고 생각 $(childDom).html()하거나$(childDom).find('some selector') ...


0

과거에 똑같은 문제가 있었으며 문제를 해결하는 유일한 방법은 iframe 페이지에 콜백을 추가하는 것입니다. 물론 iframe 컨텐츠를 제어 할 때만 작동합니다.


22
나는 당신에게 투표하지 않았지만, 당신이 그가 할 수 없다고 말한 것을 정확하게 제안했기 때문에 당신이 투표를했다고 상상합니다. 그는 구체적으로 말했습니다. "콜백을 해고하십시오."
Dave Haynes

-1

사용 onloadattrbute를 문제가 해결됩니다.

다음은 예입니다.

function a() {
alert("Your iframe has been loaded");
}
<iframe src="https://stackoverflow.com" onload="a()"></iframe>

이것이 당신이 원하는 것입니까?

자세한 내용은 여기클릭하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.