Cross-Domain 간 Iframe 크기 변경 및 정보 전달 by 오리대마왕

기록용으로 남기는 포스팅이다. 이젠 용어도 가물가물한데, 하여간 cross-domain 에 대한 script 및 iframe 등의 공격에 의한 해킹은 많이 알려져 있어서 요즘 브라우저들은 당연히 이에 대한 처리를 하고 있다. 문제가 되는 것은 선량한 용도로 쓰기 위한 방법들까지 함께 막힌다는 건데 (브라우저가 내가 선량한 시민인지 악마인지 알 수 없으니) 이러니 예전에 많이들 쓰던 iframe resizing 방법이 제대로 안먹힌다. 이를 해결한 것이 Resizing IFrames Across Domains 이다. 그리고 여기에는 iframe 간 정보전달 방법이 함께 사용된다.

Cross-domain Iframe 정보 전달


이제 더이상 script 등을 통해 iframe <-> parent 페이지 간 정보를 전달하거나 기능을 호출할 수 없다. 그럼 어떻게 정보를 넘기나? 간단하다. URL parameter로 넘긴다. 받는 쪽에서는 URL 중 parameter 부분을 parsing해서 적절히(!) 처리하면 된다. 괜히 javascript 등으로 뭔가 우회하려 하지 말고, 다른 방법은 그냥 포기하자. 간단하므로 예제는 생략하고, 더 자세한 내용은 Secure Cross-Domain Communication in the Browser 에서 확인할 수 있다.

Cross-domain Iframe 크기 변경


다음의 단계로 진행된다.
  1. iframe를 감싸고 있는 원래의 페이지를 생성함 ( Page A @ domain A)
  2. 포함되는 iframe ( Page B @ domain B ) 내부가 또하나의 iframe ( Page C @ domain A) 를 가지도록 함
  3. Page B 는 Page C 에게 자신의 size 정보를 url parameter형태로 전달함. 이렇게 하지 않으면 B->C 간 정보전달 할 수 없다.
  4. Page C 는 Page A 에게 Page B의 size 정보를 다시 넘긴다. Page C 와 Page A 는 같은 domain A 이므로 script 실행에 제약이 없다.
  5. Page A는 Page C 로 부터 얻은 Page B 의 size정보를 가지고 자신의 iframe element 의 크기를 변경한다.
즉, Page B의 사이즈가 B->C->A 의 순서로 전달된다.

대략의 소스는 다음과 같다. 이글루스의 절망적인 소스 첨부 기능은 이제 포기했다. 이쁘게 보이려는 잡스런 시도도 이젠 포기. 죄송하지만 알아서 들 보세요.

Page A:
<html>
<head>
<script type="text/javascript">
      //요 함수는 최종적으로 page C 가 호출하는 함수이다.
      function updateIFrame( height ) {
        var iframe = document.getElementById( 'iframe1' );
        iframe.setAttribute( 'height', height );
      }
</script>
</head>
<body>
<iframe id="iframe1" frameborder="1" style="margin-left: 10px;" marginheight="0"
marginwidth="0" scrolling="no" topmargin="0" width="100%" >
</iframe>
<script type="text/javascript">
//iframe 의 주소에 자신의 domain 정보를 붙여서 넘긴다.
var iframeSrc="http://domainB/pageB.htm#"+document.domain;
       var iframe = document.getElementById( 'iframe1' );
        iframe.src = iframeSrc;
</script>
</body>
</html>

Page B:
<html>
<head>
<script type="text/javascript">
//이름이 좀 거시기 한데, 원래 용도는 Page C에게 Page B의 size 정보를 건네기 위함이다.
function resizeIframe(){
        var iframe = document.getElementById( 'inneriframe' );
        var wrapper = document.getElementById( 'wrapper' );
        var height = Math.max( document.body.offsetHeight, document.body.scrollHeight );
        //정확한 domain 정보를 위해 PageA의 domain 정보를 받아서 PageC의 domain 정보로 활용한다.
        var iframeDomain = document.location.href.split( "#")[1];
        var iframeUrl = 'http://'+iframeDomain +'/pageC.html?height='+height
        iframe.src = iframeUrl;
}
</script>
</head>
<body>
<div id="wrapper">
long content....
<iframe id="inneriframe" width="10" height="10"></iframe>
<script type="text/javascript">
resizeIframe();
</script>
</div>
</body>
</html>

Page C:
<html>
  <head>
    <title>Resizing Page</title>
    <script type="text/javascript">
      function onLoad() {
        var params = window.location.search.substring( 1 ).split( '&' );
        var height;
        for( var i = 0, l = params.length; i < l; ++i ) {
          var parts = params[i].split( '=' );
          switch( parts[0] ) {
          case 'height':
            height = parseInt( parts[1] );
            break;
          }
        }
        if( typeof( height ) == 'number' ) {
          //Page A 의 updateIframe function을 실행한다.
          window.top.updateIFrame( height );
        }
      }
    window.onload = onLoad;
    </script>
  </head>
  <body>
    <p>Resizing IFrame...</p>
  </body>
</html>

완전히 테스트를 해 보지 않아서 100% 동작하는 지 확신은 못하겠지만, 대충 위의 코드들을 보면 어떤 의미인지 충분히 이해할 수 있을 것이다. 그리고 위 코드는 내가 만든게 아니라 맨 위 링크에 포함되어 있는 예제 페이지 코드에 기반하여 살짝 고친 것이다.

웹개발 손 뗀지가 2년이 되어가니 이젠 뭐 하나 기억이 나는 게 없네. @_@
@근데 나 QA인데 왜 웹 페이지 개발하고 있지? T_T

덧글

  • Tsuzuku 2008/07/28 14:05 #

    세원 나 심심해...
    대전에 놀러안와? (~=ㅅ=)~
  • 오리대마왕 2008/07/29 13:45 #

    나 지난 주말에 대전갔다왔는데... 앞으로 쭉 갈 일 없을 듯 하네. 당신이 서울에 와. 순대먹여줄께
  • Tsuzuku 2008/07/31 15:15 #

    8월7일에 서울가기는 하는데... 서울역 근처에 포럼이 있어서...
    그런데.. 평일이라..그것도 금요일도 아니고 목요일...
    놀 수 있을지 모르겠네 =_=a
  • 오리대마왕 2008/07/31 21:20 #

    서울역 근처라면 코피나 한잔 하자꾸나. 금요일에 서울 사무실에서 일하겠다고 해. 같이 뜨거운 밤을 보내자구.
  • Tsuzuku 2008/08/05 11:02 #

    =_=;; 미안..
    금요일까지 베타버전을 미국에 넘겨주기로 되어버렸다 OTL
    세미나 갔다가 바로 다시 대전으로 와야되어버렸다... T-T

    담에 시간나면 보자구~~
    아참.. 11월인가 그때 인재 결혼한다더라.. 어제 우연히 만났는데 그러데..
  • hyen 2009/05/18 12:03 # 삭제

    좋은글 감사합니다. 많은 도움이 되었습니다.^^
※ 로그인 사용자만 덧글을 남길 수 있습니다.