티스토리 뷰
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를 생성하는 방법은 아래와 같다. 필요한 상황을 골라서 사용하면 된다.
- Window.open (새 창을 만들고 새 창을 참조할 때),
- Window.opener (새 창을 만든 window를 참조할 때),
- HTMLIFrameElement.contentWindow (en-US) (부모 window에서 임베디드된 <iframe>을 참조할 때),
- Window.parent (en-US) (임베디드된 <iframe>에서 부모 window를 참조할 때),
- Window.frames (en-US) + an index value (named or numeric).
이렇게 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);
다음 포스팅에서 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
'web' 카테고리의 다른 글
[WEB] window, DOM, BOM (0) | 2021.11.02 |
---|---|
Server-Side Rendering과 Client-Side Rendering에 대한 개념 이해 (0) | 2021.08.30 |
[web] select box에 동적으로 option추가할 때 발생한 이슈 (0) | 2021.04.15 |
[HTML] id와 name (0) | 2021.03.07 |
[Web] highchart highcharts.src.js:13611 Uncaught TypeError: Cannot set property 'index' of undefined (0) | 2020.12.16 |
- Total
- Today
- Yesterday
- stackframe
- Java
- 재귀함수
- 퀵정렬
- BFS
- 알고리즘
- 구조체
- 소프트웨어
- 세마포어
- 배열
- 스텍
- javascript
- 운영체제
- C
- 클래스
- 자료구조
- 병행프로세스
- 입출력장치
- dfs
- 교착상태
- 동적프로그래밍
- react
- Stack
- 최단경로
- 인접행렬
- 이진탐색
- C++
- client side rendering
- server side rendering
- 인접리스트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |