[javascript] 컨텐츠를 기반으로 iframe 크기 조정

iGoogle과 유사한 응용 프로그램을 만들고 있습니다. 다른 응용 프로그램 (다른 도메인)의 컨텐츠는 iframe을 사용하여 표시됩니다.

iframe 콘텐츠의 높이에 맞게 iframe의 크기를 어떻게 조정합니까?

Google이 사용하는 자바 스크립트를 해독하려고 시도했지만 난독 화되었으며 웹 검색은 지금까지 아무런 성과가 없었습니다.

업데이트 : 다른 도메인에서 콘텐츠가로드되므로 동일한 출처 정책이 적용됩니다.



답변

우리는 이런 유형의 문제를 겪었지만 상황과는 약간 반대입니다. 우리는 다른 도메인의 사이트에 불법 복제 된 컨텐츠를 제공하고 있었기 때문에 동일한 출처 정책 도 문제였습니다. Google을 트롤링하는 데 많은 시간을 소비 한 후에, 우리는 결국 (어떤 ..) 실행 가능한 솔루션을 찾았습니다.

동일한 출처 정책을 사용하는 방법이 있지만 iframed 컨텐츠와 프레임 페이지 모두에서 변경이 필요하므로 양쪽에 변경을 요청할 수있는 기능이 없으면이 방법이 유용하지 않습니다. 두렵습니다.

자바 스크립트는 자체 도메인의 페이지 또는 페이지가있는 페이지와 통신 할 수 있지만 프레임이있는 페이지와는 통신 할 수 없습니다 (예 : 다음과 같은 경우).

 www.foo.com/home.html, which iframes
 |-> www.bar.net/framed.html, which iframes
     |-> www.foo.com/helper.html

그런 다음 (iframed) 및 (같은 도메인) 과 home.html통신 할 수 있습니다 .framed.htmlhelper.html

 Communication options for each page:
 +-------------------------+-----------+-------------+-------------+
 |                         | home.html | framed.html | helper.html |
 +-------------------------+-----------+-------------+-------------+
 | www.foo.com/home.html   |    N/A    |     YES     |     YES     |
 | www.bar.net/framed.html |    NO     |     N/A     |     YES     |
 | www.foo.com/helper.html |    YES    |     YES     |     N/A     |
 +-------------------------+-----------+-------------+-------------+

framed.html메시지를 보낼 수 있습니다 helper.html(iframe이)하지만, 하지 home.html (아이는 부모 도메인 간 통신 할 수 없습니다).

여기서 핵심은 helper.html에서 메시지를 수신 framed.html하고 통신 할 수 있다는 것 입니다 home.html.

따라서 기본적으로 framed.html로드 할 때 자체 높이 helper.html를 계산하고 메시지를 전달 home.html한 다음 framed.html앉은 iframe의 크기를 조정할 수 있습니다 .

우리의 메시지를 전달하는 것으로 가장 간단한 방법 framed.html으로는 helper.htmlURL을 인수 통해서였다. 이렇게하려면 지정된 framed.htmliframe이 src=''있습니다. onload발사 되면 자체 높이를 평가 하고이 시점에서 iframe의 src를helper.html?height=N

페이스 북이 그것을 처리하는 방법에 대한 설명 이 있습니다.


암호

에서 www.foo.com/home.html다음과 같은 자바 스크립트 코드가 필요합니다 (이는 덧붙여 말하자면, 어떤 도메인은 .js 파일에서로드 할 수 있습니다 ..) :

<script>
  // Resize iframe to full height
  function resizeIframe(height)
  {
    // "+60" is a general rule of thumb to allow for differences in
    // IE & and FF height reporting, can be adjusted as required..
    document.getElementById('frame_name_here').height = parseInt(height)+60;
  }
</script>
<iframe id='frame_name_here' src='http://www.bar.net/framed.html'></iframe>

에서 www.bar.net/framed.html:

<body onload="iframeResizePipe()">
<iframe id="helpframe" src='' height='0' width='0' frameborder='0'></iframe>

<script type="text/javascript">
  function iframeResizePipe()
  {
     // What's the page height?
     var height = document.body.scrollHeight;

     // Going to 'pipe' the data to the parent through the helpframe..
     var pipe = document.getElementById('helpframe');

     // Cachebuster a precaution here to stop browser caching interfering
     pipe.src = 'http://www.foo.com/helper.html?height='+height+'&cacheb='+Math.random();

  }
</script>

내용 www.foo.com/helper.html:

<html>
<!--
This page is on the same domain as the parent, so can
communicate with it to order the iframe window resizing
to fit the content
-->
  <body onload="parentIframeResize()">
    <script>
      // Tell the parent iframe what height the iframe needs to be
      function parentIframeResize()
      {
         var height = getParam('height');
         // This works as our parent's parent is on our domain..
         parent.parent.resizeIframe(height);
      }

      // Helper function, parse param from request string
      function getParam( name )
      {
        name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
        var regexS = "[\\?&]"+name+"=([^&#]*)";
        var regex = new RegExp( regexS );
        var results = regex.exec( window.location.href );
        if( results == null )
          return "";
        else
          return results[1];
      }
    </script>
  </body>
</html>


답변

다른 도메인에서 iframe 컨텐츠를 처리 할 필요가없는 경우이 코드를 사용하면 문제가 완전히 해결되고 간단합니다.

<script language="JavaScript">
<!--
function autoResize(id){
    var newheight;
    var newwidth;

    if(document.getElementById){
        newheight=document.getElementById(id).contentWindow.document .body.scrollHeight;
        newwidth=document.getElementById(id).contentWindow.document .body.scrollWidth;
    }

    document.getElementById(id).height= (newheight) + "px";
    document.getElementById(id).width= (newwidth) + "px";
}
//-->
</script>

<iframe src="usagelogs/default.aspx" width="100%" height="200px" id="iframe1" marginheight="0" frameborder="0" onLoad="autoResize('iframe1');"></iframe>


답변

https://developer.mozilla.org/en/DOM/window.postMessage

window.postMessage ()

window.postMessage는 출처 간 통신을 안전하게 활성화하는 방법입니다. 일반적으로, 다른 페이지의 스크립트는 스크립트를 실행 한 페이지가 동일한 프로토콜 (일반적으로 http), 포트 번호 (http의 기본값 인 80) 및 호스트 (모듈로)의 위치에있는 경우에만 서로 액세스 할 수 있습니다. 두 페이지에서 동일한 값으로 설정되는 document.domain). window.postMessage는 올바르게 사용될 때 안전한 방식으로이 제한을 피하기 위해 제어 된 메커니즘을 제공합니다.

요약

window.postMessage를 호출하면 실행해야하는 보류중인 스크립트가 완료 될 때 대상 창에서 MessageEvent가 전달됩니다 (예 : window.postMessage가 이벤트 핸들러에서 호출 된 경우 남아있는 이벤트 핸들러, 이전에 설정된 보류 시간 초과 등). ). MessageEvent에는 시간 창에서 window.postMessage를 호출하는 창에서 기본 문서의 원점에 해당하는 원점 속성 인 window.postMessage에 제공되는 첫 번째 인수의 문자열 값으로 설정되는 data 속성 인 message 유형이 있습니다. postMessage가 호출되었고 window.postMessage가 호출되는 창인 소스 특성입니다. (이벤트의 다른 표준 속성에는 예상 값이 있습니다.)

iFrame을-리사이 라이브러리와 함께 iframe을 그것의 내용에 크기를 유지하기 위해 PostMessage를 사용 MutationObserver 내용에 대한 변경 사항을 감지하고 jQuery를에 의존하지 않습니다.

https://github.com/davidjbradshaw/iframe-resizer

jQuery : 도메인 간 스크립팅의 장점

http://benalman.com/projects/jquery-postmessage-plugin/

iframe 윈도우 크기 조정 데모가 있습니다 …

http://benalman.com/code/projects/jquery-postmessage/examples/iframe/

이 기사는 jQuery에 대한 종속성을 제거하는 방법을 보여줍니다 … Plus에는 유용한 정보가 많이 있으며 다른 솔루션에 대한 링크가 있습니다.

http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/

Barebones 예제 …

http://onlineaspect.com/uploads/postmessage/parent.html

window.postMessage에 HTML 5 작업 초안

http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages

교차 창 메시징에 대한 John Resig

http://ejohn.org/blog/cross-window-messaging/


답변

jQuery를 사용하는 가장 간단한 방법 :

$("iframe")
.attr({"scrolling": "no", "src":"http://www.someotherlink.com/"})
.load(function() {
    $(this).css("height", $(this).contents().height() + "px");
});


답변

http://www.phinesolutions.com/use-jquery-to-adjust-the-iframe-height.html 의 솔루션 은 훌륭하게 작동합니다 (jQuery 사용).

<script type=”text/javascript”>
  $(document).ready(function() {
    var theFrame = $(”#iFrameToAdjust”, parent.document.body);
    theFrame.height($(document.body).height() + 30);
  });
</script>

나는 길이에 30을 더해야한다는 것을 모른다 .1은 나를 위해 일했다.

참고 : iFrame에 “높이”속성이 이미 있으면 style = “height : xxx”만 추가됩니다. 이것은 당신이 원하는 것이 아닐 수도 있습니다.


답변

다른 모든 답변이 나이가 들기 때문에 조금 늦을 수도 있습니다 🙂 그러나 … 여기 내 솔루션이 있습니다. 실제 FF, Chrome 및 Safari 5.0에서 테스트되었습니다.

CSS :

iframe {border:0; overflow:hidden;}

자바 스크립트 :

$(document).ready(function(){
    $("iframe").load( function () {
        var c = (this.contentWindow || this.contentDocument);
        if (c.document) d = c.document;
        var ih = $(d).outerHeight();
        var iw = $(d).outerWidth();
        $(this).css({
            height: ih,
            width: iw
        });
    });
});

이것이 누군가에게 도움이되기를 바랍니다.


답변

마지막으로을 사용하여 iframe에서 부모 웹 사이트로 데이터를 보내는 다른 솔루션을 찾았습니다 window.postMessage(message, targetOrigin);. 여기 내가 어떻게했는지 설명합니다.

사이트 A = http://foo.com
사이트 B = http://bar.com

SiteB가 siteA 웹 사이트에로드 중입니다

SiteB 웹 사이트에이 줄이 있습니다

window.parent.postMessage("Hello From IFrame", "*"); 

또는

window.parent.postMessage("Hello From IFrame", "http://foo.com");

그런 다음 siteA에는 다음 코드가 있습니다.

// Here "addEventListener" is for standards-compliant web browsers and "attachEvent" is for IE Browsers.
var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
var eventer = window[eventMethod];


var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";

// Listen to message from child IFrame window
eventer(messageEvent, function (e) {
   alert(e.data);
   // Do whatever you want to do with the data got from IFrame in Parent form.
}, false); 

보안 연결을 추가하려는 경우 eventer(messageEvent, function (e) {})

if (e.origin == 'http://iframe.example.com') {
    alert(e.data);
    // Do whatever you want to do with the data got from IFrame in Parent form.
}

IE의 경우

내부 IFrame :

 window.parent.postMessage('{"key":"value"}','*');

외부:

 eventer(messageEvent, function (e) {
   var data = jQuery.parseJSON(e.data);
   doSomething(data.key);
 }, false);