티스토리 뷰

web

[WEB] Window.postMessage()

tonirr 2021. 11. 19. 20:00

WebRTC로 화상 기능을 개발하면서 기존 창과 새 창 사이 메세지를 주고 받아야 하는 상황에서

Window.postMessage()를 통해 기존 창의 값을 참조할 수 있었다. 

처음 postMessage를 사용하기로 하였을 때 창 간에 메세지를 주고 받는다는 것이 생소해서 서칭과정이 길었다. 

이번 포스팅에서 Window.postMessage()의 개념과 예제를 상기시키면서 정리하고 이후 포스팅에서 

React Hook에서 Window.postMessage()를 사용하여 개발한 과정 및 발생 이슈들을 정리해보려고 한다.

 

Window.postMessage()란?

window.postMessage() 메소드는 Window 오브젝트 사이에서 안전하게 cross-origin 통신을 할 수 있게 합니다. 예시로, 페이지와 생성된 팝업 간의 통신이나, 페이지와 페이지 안의 iframe 간의 통신에 사용할 수 있습니다.

 

일반적으로, 다른 페이지 간의 스크립트는 각 페이지가 같은 프로토콜, 포트 번호와 호스트을 공유하고 있을 때에("동일 출처 정책"으로도 불려 집니다.) 서로 접근할 수 있습니다. window.postMessage()는 이 제약 조건을 안전하게 우회하는 기능을 제공합니다.

MDN에서는 이렇게 설명하고 있다. 

 

나는 기존 창과 새창 간에 통신할 때에 사용하였는데,이 경우 동일 근원 출처 정책으로 인해 기존 창과 새 창이 각각의 window를 가지고 있어 통신할 수 없는 것이 원칙이나 Window.postMessage를 사용하면 안전하게 기존 창과 새 창이 통신할 수 있다.

 

문법

아래 과정을 통해 하나의 window는 다른 window를 참조할 수 있다. 하나의 예시이고 참조 방식에 따라 방법은 달라진다.

targetWindow = window.opener 	// 새 창을 만들고 그 새창을 참조할 경우

 

targetWindow를 만든 후 아래 과정처럼 사용할 수 있다. 

targetWindow.postMessage(message, targetOrigin, [transfer]);

targetWindow를 생성하는 방법은 아래와 같다. 필요한 상황을 골라서 사용하면 된다.

이렇게 targetWindow를 생성한 후 다른 window에 보내질 데이터를 message 부분에 실어서 보낸다. 

targetOrigin 에서는 targetWindow 의 origin을 지정하며 별도로 지정하지 않음("*")으로 지정하거나 URI를 작성한다.

 

 

디스페치 이벤트

아래 스크립트를 실행할 경우 메시지를 수신하는 window측에서 전달된 메시지를 받을 수 있다.

window.addEventListener("message", receiveMessage, false);

function receiveMessage(event)
{
  if (event.origin !== "http://example.org:8080")
    return;

  // ...
}

 

 

예제

새 창을 만들고 새 창을 참조하는 경우(Window.open)를 통해 이해해보자 

/*
 * <http://example.com:8080>에 있는 윈도우 A의 스크립트:
 */

// 새 창을 참조하는 객체 popup을 만든다.
var popup = window.open(...popup details...);

// https://secure.example.net 도메인에 아래와 같은 메세지를 보낸다.
popup.postMessage("The user is 'bob' and the password is 'secret'",
                  "https://secure.example.net");

// http://example.com 도메인에 아래와 같은 메세지를 보낸다.
popup.postMessage("hello there!", "http://example.com");

// <http://example.com:8080>에서 메세지를 받는 함수
function receiveMessage(event)
{
  // origin 체크를 통해 message를 신뢰할 것인지 확인한다.
  if (event.origin !== "http://example.com")
    return;

  // event.source is popup
  // event.data 가 "hi there yourself!  the secret response is: rheeeeet!"
}
// <http://example.com:8080>에 이벤트 등록 한다.
window.addEventListener("message", receiveMessage, false);
/*
 * In the popup's scripts, running on <http://example.com>:
 */
function receiveMessage(event)
{
  //  origin 체크를 통해 message를 신뢰할 것인지 확인한다.
  if (event.origin !== "http://example.com:8080")
    return;

  // event.source가 window.opener라면 event.data는 "hello there!"이 될 것이다.

  // event.origin은 <http://example.com> 즉 새창을 띄운 origin 창을 말하며 
  // origin 창에 아래 메세지를 보낸다. 
  event.source.postMessage("hi there yourself!  the secret response " +
                           "is: rheeeeet!",
                           event.origin);
}

// <http://example.com>에 이벤트 등록을 한다.
window.addEventListener("message", receiveMessage, false);

 

 

서로 도메인이 다른 Controller Window와 Receiver Window가 message를 주고 받을 수 있다

 

다음 포스팅에서 React Hook 프로젝트에서 window.postMessage()를 사용하는 과정에서 

이벤트 등록이 안되면서 메세지를 불러오지 못하거나 컴포넌트 이동중에 여러번 이벤트 등록되어 window message를 주고받는 과정에서 이슈가 발생하는 등의 시행착오를 하나씩 정리해보려고 한다. 

 

참고

https://developer.mozilla.org/ko/docs/Web/API/Window/postMessage

https://blog.teamtreehouse.com/cross-domain-messaging-with-postmessage

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함