투케이2K

521. (javaScript) [간단 소스] 자바스크립트 window.opener.postMessage Cross-window 팝업창 데이터 통신 방식 설명 정리 본문

JavaScript

521. (javaScript) [간단 소스] 자바스크립트 window.opener.postMessage Cross-window 팝업창 데이터 통신 방식 설명 정리

투케이2K 2026. 4. 1. 19:39
728x90
반응형

[개발 환경 설정]

개발 툴 : Edit++ / Vscode

개발 언어 : JavaScript

 

[설명 정리]

-----------------------------------------------------------------------------------------
[사전 설명 및 설정 사항]
-----------------------------------------------------------------------------------------

- 개발 환경 : Web


- 개발 기술 : JavaScript (자바스크립트) / 동적 html / 동적 Script / window open


- 사전) 👉 window.open 기능 간편 설명 : 

  >> window.open() 은 브라우저에서 새 창이나 새 탭을 열거나, 기존에 이름 붙인 창을 재사용할 때 사용하는 함수입니다

  >> window.open() 은 주로 외부 링크를 새 탭으로 열거나, 팝업(작은 창) 형태로 보조 UI를 띄울 때 사용됩니다

  >> window.open() target 주요 인자 값 : 

    - '_blank': 새 탭/창

    - '_self': 현재 창(일반 링크와 동일)

    - '_parent', '_top': 프레임/아이프레임 계층에 영향

-----------------------------------------------------------------------------------------





-----------------------------------------------------------------------------------------
[설명 정리]
-----------------------------------------------------------------------------------------

1. window.opener.postMessage() 는 팝업 창 (자식 창) 이 자신을 연 부모 창 (parent window) 에게 데이터를 전달할 때 사용하는 안전한 Cross-window 통신 방식입니다.

  ✔️ 부모 → window.open() → 자식(팝업)

  ✔️ 자식 → window.opener.postMessage() → 부모


2. window.opener.postMessage() 는 부모가 window.open() 으로 자식 팝업을 열은 후 데이터를 주고 받기 위해 사용합니다.

  >> postMessage 는 origin 이 달라도 안전하게 통신할 수 있도록 설계된 표준 API 입니다.


3. window.opener.postMessage() 사용 시 주의점 : 

  >> Blob URL 또는 file:// 로 여는 경우 cross-origin 에러 발생 : 

    - 이 경우에도 postMessage 를 통한 데이터 교환은 가능하지만 child.onload, child.document 접근은 불가능합니다.

  >> 부모에서 child.onload 쓰려 하면 SecurityError 발생 : 

    - cross-origin 접근이기 때문에 부모에서 child.onload 를 쓰면 SecurityError 에러가 발생합니다.


4. ✅ [부모 입장] window.opener.postMessage() 시 자식에게 데이터 전송 방법

  >> [1] 부모 : window.open 사용해 자식 새창 열기 수행

    const child = window.open("child.html", "popup");

  >> [2] 자식 : window.onload 이벤트에서 부모의 이벤트 감지를 위한 window.addEventListener('message') 리스너 등록

    window.onload = function() {
      console.log('window open success');

      try { 
          
        // ✔️ [부모가 전달한 window.opener.postMessage 를 받기 위한 이벤트 리스너 등록]
        window.addEventListener('message', (event) => {                  
          console.warn("window.addEventListener(message) : receive : ", JSON.stringify(event));
          console.warn('[event.data] : ', event.data, ' / [event.origin] : ', event.origin);


          // ✔️ TWOK_POPUP_CLOSE : Window 팝업창 닫기 명령 수신
          if (event.data.type !== null && event.data.type !== undefined && event.data.type !== '' && event.data.type == 'TWOK_POPUP_CLOSE'){
            console.log('window.open : TWOK_POPUP_CLOSE : success');
            
            window.close(); // ✔️ open 된 팝업창 닫기 처리
          }

        });
      } 
      catch(err) { 
        console.error('chile window onload : exception : ', err); 
      }

    };

  >> [3] 부모 : 자식 window.open 이후 postMessage 사용해 자식에게 메시지 전송

    setTimeout(() => {
                          
      console.log('setTimeout : window.opener.postMessage : send');

      child.postMessage(
        { type: 'TWOK_POPUP_CLOSE' },  // 보낼 데이터
        '*' // targetOrigin (실서비스에서는 도메인 지정!)
      );

    }, 2000); // 2초뒤에 전송


5. ✅ [자식 입장] window.opener.postMessage() 시 부모에게 데이터 전송 방법

  >> [1] 부모 : window.onload 이벤트에서 부모의 이벤트 감지를 위한 window.addEventListener('message') 리스너 등록

    window.onload = function() {
      console.log('window onload start');

      try { 
          
        // ✔️ [자식이 전달한 window.opener.postMessage 를 받기 위한 이벤트 리스너 등록]
        window.addEventListener('message', (event) => {                  
          console.warn("window.addEventListener(message) : receive : ", JSON.stringify(event));
          console.warn('[event.data] : ', event.data, ' / [event.origin] : ', event.origin);


          // ✔️ TWOK_POPUP_READY : Window 팝업창 준비 완료 명령 수신
          if (event.data.type !== null && event.data.type !== undefined && event.data.type !== '' && event.data.type == 'TWOK_POPUP_READY'){
            console.log('window.open : TWOK_POPUP_READY : success');
            
          }

        });
      } 
      catch(err) { 
        console.error('window onload : exception : ', err); 
      }

    };


  >> [2] 부모 : window.open 사용해 자식 새창 열기 수행

    const child = window.open("child.html", "popup");

  >> [3] 자식 : window.onload 이벤트에서 부모에게 window.opener.postMessage 메시지 전송 수행

    window.onload = function() {
      console.log('window open success');

      setTimeout(() => {

        try { 
          window.opener.postMessage({ type: 'TWOK_POPUP_READY', payload: { ts: Date.now() } }, '*');  // ✔️ 자식 >> 부모 메시지 전달
        } 
        catch(err) { 
          console.error('window.opener.postMessage : exception : ', err); 
        }

      }, 1000); 

    };

-----------------------------------------------------------------------------------------





-----------------------------------------------------------------------------------------
[참고 사이트]
-----------------------------------------------------------------------------------------

[간단 소스] 자바스크립트 window.open 사용해 새창 팝업창 열기 후 window.opener.postMessage 메시지 전달 수행

https://kkh0977.tistory.com/8668

https://blog.naver.com/kkh0977/224202970329


[간단 소스] 자바스크립트 동적 html 코드 작성, new Blob 및 URL.createObjectURL 사용해 window.open 새창 열기

https://kkh0977.tistory.com/8452

https://blog.naver.com/kkh0977/224097132149


[자바스크립트 브라우저 사이즈, 해상도 구하기 및 window open 윈도우 창 열기 실시]

https://kkh0977.tistory.com/847

https://blog.naver.com/kkh0977/222392594793?trackingCode=blog_bloghome_searchlist


[자바스크립트 window open close 사용해 현재 브라우저 창 닫기 수행 - 브라우저 종료]

https://blog.naver.com/kkh0977/223203344998?trackingCode=blog_bloghome_searchlist


[모바일] 내부 window open 상태 감지 및 새로운 웹뷰 작업 로직 수행 방법

https://blog.naver.com/kkh0977/222609480598?trackingCode=blog_bloghome_searchlist

-----------------------------------------------------------------------------------------
 
728x90
반응형
Comments