개발자포럼

개발관련 이슈 및 팁을 공유해보세요.

프론트엔드

프론트엔드 개발에 대한 주제포럼입니다.

#postMessage 를 이용한 서로 다른 도메인간 데이터 주고 받기

일반적으로 스크립트는 동일 근원 정책에 의해, 프로토콜, 도메인, 포트 중 어느 하나라도 다른 경우엔 다른 윈도우와 통신할 수 없습니다.

하지만, window.postMessage()를 사용하면 안전하게 서로 다른 도메인을 가진 다른 윈도우와 통신할 수 있게 됩니다.


간단한 예제코드는 아래와 같습니다.

otherWindow.postMessage(message, targetOrigin);


otherWindow:

  • window.open() 의 응답으로 얻은 윈도우 객체
  • iframe 의 contentWindow 프로퍼티로 가져온 윈도우 객체
  • window.frames 프로퍼티에서 가져온 윈도우 객체


message:

  • 전달할 데이터 (JSON도 가능하다)


targetOrigin:

  • 메시지를 받을 타겟 오리진. 프로토콜, 도메인, 포트를 URL 형태로 전달한다.


"*" 문자열로 모든 윈도우로 전달할 수도 있지만, 악성 스크립트에서 해당 이벤트를 받을 수 있으므로 가능한 명시하는 것이 좋습니다.


예를 들어, 아래 코드는 example 이라는 아이디를 가진 <iframe>으로 데이터를 보내는 예제입니다.

<iframe id="example" src="https://other-domain.com/receive.html"></iframe>
<script type="text/javascript">
  var iframeWindow = document.getElementById("example").contentWindow;
  iframeWindow.postMessage("hello world!","https://other-domain.com");
</script>


받는 측에서는 윈도우의 message 이벤트를 통해 데이터를 받을 수 있습니다.

위의 예제코드상으로 https://other-domain.com/receive.html 파일에 작성되어야 하는 내용입니다.


<script type="text/javascript">
window.addEventListener("message", function (e) {
  if (e.origin === "https://domain.com") { // 위의 예제 코드가 작성된 곳의 도메인주소
    console.log(e.data); // "hello world!" 가 출력된다.
    e.source.postMessage("hi", "https://domain.com"); // e 객체를 활용하여, 메시지를 보낸 곳으로 다시 메시지를 보낼 수 있다.
  }
});
</script>


window.postMessage()를 사용할 때 몇 가지 주의할 점이 있습니다.


1. 메시지를 받는 윈도우에서 에러가 발생해도, 메시지를 보낸 윈도우에서는 알 수 없다.
2. 보내는 윈도우에서 "document.domain"의 속성을 변경해도, 이벤트의 "origin" 값은 변경되지 않는다.
3. 메시지를 보내는 윈도우가 "javascript:"나 "data:" URL일 경우엔, 이벤트의 "origin" 속성을 해당 스크립트를 로드한 페이지이다.
4. 크롬 익스텐션에서 메시지를 보내는 경우, "source"는 항상 null로 설정된다.


좀 더 자세한 내용은 아래 링크를 참고하면 되며,

https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage


postMessage 브라우져별 지원여부는 아래 링크를 참고하시면 됩니다.
https://caniuse.com/#search=postMessage

알쯔
LV.16