HTML5 API - PostMessage



HTML5에서는 postMessage API와 XMLHttpRequest 레벨2 같은 새로운 통신 방식이 추가됐으며, 이로써 기존 보안 정책상의 이유로 허용되지 않았던 타 도메인과의 통신 또한 가능해졌습니다.


또한, 기존의 보안정책을 개선한 이유는 컨텐츠 전송방식이 현 트랜드와 맞지 않았기 떄문이었습니다.

예를 들면, 타 사이트의 컨텐츠를 가공하여 새로운 컨텐츠를 생산하는 매시업과 같은 기능을 구현하는데 어려움이 많았다는 것이었습니다.




postMessage API 사용방법:



1. 송신 페이지


- iframe 객체가 포함하는 페이지(http://sof.fpscamp.com/sof.htm)에 해당 데이터를 postMessage 메서드를 이용하여 전송한다.


  1. document.getElementById('sof').contentWindow.postMessage(document.getElementById('requestMsg').value, 'http://sof.fpscamp.com');


- 송신 페이지에 포함된 iframe(http://sof.fpscamp.com/sof.htm) 객체

  1. <div><iframe id="sof" name="sof" src="http://sof.fpscamp.com/sof.htm?12312312" width="1000" height="1000"></iframe></div>


2. 수신 페이지

window 객체 이벤트인 onmessage 이벤트 핸들러를 할당하여 송신자의 요청을 처리한다.

1. e.origin: 송신자의 도메인을 반환한다.(해당 속성으로 무작위로 전송되는 데이터 처리를 제한시킨다.(허용 도메인만 처리))

2. e.data: 송신자의 데이터를 반환한다.


  1.      bind(window, 'message', function (e) {
  2.         if (e.origin === 'http://m.fpscamp.com') {
  3.             document.getElementById('msg_list').innerHTML += '<li style="margin-top:4px;">' + e.data + '(' + e.origin + ' 도메인에서 메시지를 전송함)</li>';            
  4.         }
  5.     });




아래는 postMessage API를 활용한 타 도메인간의 전송 방법을 다룬 코드 예제입니다.


- 송신 페이지(http://m.fpscamp.com)

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4.     <title>postMessage</title>
  5. </head>
  6. <body>
  7. <script type="text/javascript">
  8. //<![CDATA[
  9.  
  10.     bind(window, 'message', function (e) {
  11.         if (e.origin === 'http://sof.fpscamp.com') {
  12.             document.getElementById('msg_list').innerHTML += '<li style="margin-top:4px;">' + e.data + '(' + e.origin + ' 도메인에서 메시지를 전송함)</li>';
  13.         }
  14.     });
  15.  
  16.     function sendMsg() {
  17.         document.getElementById('sof').contentWindow.postMessage({}, 'http://sof.fpscamp.com');
  18.     }
  19.  
  20.     // 이벤트 할당
  21.     function bind(elem, type, handler, capture) {
  22.         type = typeof type === 'string' && type || '';
  23.         handler = handler || function () { ; };
  24.  
  25.         if (elem.addEventListener) {
  26.             elem.addEventListener(type, handler, capture);
  27.         }
  28.         else if (elem.attachEvent) {
  29.             elem.attachEvent('on' + type, handler);
  30.         }
  31.  
  32.         return elem;
  33.     };
  34.  
  35.  
  36. //]]>
  37. </script>
  38. <input type="text" id="requestMsg" />
  39. <input type="button" value="postMessage" onclick="sendMsg()" />
  40.  
  41. <div id="text_container" style="width:100%;height:100%"><ul id="msg_list"></ul></div>
  42.  
  43. <div><iframe id="sof" name="sof" src="http://sof.fpscamp.com/sof.htm?12312312" width="1000" height="1000"></iframe></div>
  44. </body>
  45. </html>



- 수신 페이지(http://sof.fpscamp.com)

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4.     <title>postMessage</title>
  5. </head>
  6. <body>
  7. <script type="text/javascript">
  8. //<![CDATA[
  9.  
  10.  
  11.     bind(window, 'message', function (e) {
  12.         if (e.origin === 'http://m.fpscamp.com') {
  13.             document.getElementById('msg_list').innerHTML += '<li style="margin-top:4px;">' + e.data + '(' + e.origin + ' 도메인에서 메시지를 전송함)</li>';            
  14.         }
  15.     });
  16.  
  17.     function sendMsg() {
  18.         top.window.postMessage(document.getElementById('responseMsg').value, 'http://m.fpscamp.com');
  19.     }
  20.  
  21.     // 이벤트 할당
  22.     function bind(elem, type, handler, capture) {
  23.         type = typeof type === 'string' && type || '';
  24.         handler = handler || function () { ; };
  25.  
  26.         if (elem.addEventListener) {
  27.             elem.addEventListener(type, handler, capture);
  28.         }
  29.         else if (elem.attachEvent) {
  30.             elem.attachEvent('on' + type, handler);
  31.         }
  32.  
  33.         return elem;
  34.     };
  35.  
  36.  
  37. //]]>
  38. </script>
  39. <input type="text" id="responseMsg" />
  40. <input type="button" value="serMessage" onclick="sendMsg()" />
  41.  
  42. <div id="text_container" style="width:100%;height:100%"><ul id="msg_list"></ul></div>
  43. </body>
  44. </html>

한 가지 유념할 부분으로는 컨텐츠에 접근하는 도메인이 서로 다르다는 것입니다. (postMessage API의 핵심요소)



페이지 실행결과: