관리 메뉴

JIE0025

[개발/JS] 다른 모듈의 팝업을 호출하여 발생한 Cross-Origin 문제 해결과정 - postMessage()  본문

백엔드/이슈, 트러블슈팅

[개발/JS] 다른 모듈의 팝업을 호출하여 발생한 Cross-Origin 문제 해결과정 - postMessage() 

Kangjieun11 2024. 12. 3. 00:07
728x90

 

✅ 문제상황

A모듈의 메뉴에서 C모듈의 팝업을 호출한다. 

C모듈 팝업에서 버튼한개를 클릭하면 공통쪽 팝업이 뜨는데...

 

 

여기에서 공통 팝업이 제대로 뜨지 않는 문제가 발생했다.

 

 

✅  해결 과정

코드 확인 결과, 공통 팝업을 띄우기 위해선

 

1. 메뉴인경우 해당 페이지의 정보를 저장한다. 

-->  A모듈 메뉴1 에서 공통팝업 호출시 A의 정보저장 

 

2. 해당 페이지 정보가 없는 경우 (ex 팝업)  그 부모의 정보를 가져와서 저장한다.

-->  A모듈에  메뉴1에서  A모듈 팝업1을 호출한 다음 공통팝업 호출시    팝업1의 부모인 메뉴1의 정보 저장 

 

 

문제가 생겼던 부분은 

이 경우는 A에서 C팝업을 호출했기 떄문에 부모의 정보를 제대로 가져오지 못하여 발생하는 것이었다.

 

 

 

크로스오리진을 해결하기 위해선 postMessage를 이용하여 값을 전달하는 방법이 있다. 

 

 

 

✅   postMessage()

다른 도메인간 메세지 송수신이 가능한 API

 

같은 오리진 정책때문에  기본적으로는 서로 다른 도메인에서 데이터를 주고 받을 수 없다. 

postMessage()는 이를 안전하게 우회할 수 있게 도와준다.

 

 

예를들어 페이지 - 팝업,  페이지 - iframe 등 서로 다른 윈도우 객체간 데이터를 주고받는데에도 사용될 수 있다. 

 

 

postMessage(message, targetOrigin, transfer);

 

message : 전송할 데이터 

targetOrigin : 메세지 받을 도메인

transfer : (선택) 객체 전송시 소유권 전달 

 

 

Example 

"https://example.com"라는 도메인으로

"Hello"라는 문자열 객체를 전송한다고 가정하자. 

popup.postMessage("Hello!", "https://example.com");

 

 

message 수신 

window.addEventListener("message", (event) => {
  
  // 나한테 보낸 메시지가 신뢰할 수 있는 출처에서 온 것인지 확인하기 위함
  if (event.origin !== "https://example.com") return; 
  
  console.log(event.data); // 전송받은 데이터 
});

 

 

포스트메세지는 출처가 다른 여러곳에서 자유롭게 메세지를 주고받는 기능인데

이게 보안 위험으로 넘어갈 수 있기 떄문에 

나한테 보낸 메세지인지 확인하기 위한 코드가 추가된다.

 

 

메인페이지에서 팝업창 열때 데이터를 보내준다.

const popup = window.open("https://example.com/popup");
parent = {};
parent.infoA = "aa";
parent.infoB = "bb";
popup.postMessage({ param: parent }, "https://example.com");

 

// 팝업에서 데이터 수신
window.addEventListener("message", (event) => {
  if (event.origin !== "https://example.com") return; // 보안 체크
  console.log(event.data); 
});

 

 

이런식으로 필요한 데이터를 넘기면 되는데...

 

 

내 경우엔 팝업 호출하는 내부 코드에 postMessage가 이미 존재했다.

 (이미 팝업창을 띄우는 과정에서 postMessage를 사용하고 있었다)

 

 

그래서 A-메뉴에서 버튼클릭하는 순간  (팝업 호출하는쪽)

해당 메뉴의 정보를 param으로 넘겨주는것만으로도 해결할 수 있었다.

 

var parent = {}

parent.menuInfoA =  aa
parent.menuInfoB =  bb
parent.menuInfoC =  cc

 

functionPopupOpen(  {type :"VIEW",  param: { otherValue: otherValue , parent: parent }}  );

 

 

최종적으로 가져온 값을 갖고  팝업 오픈전 설정시 사용하니

정상 작동 확인할 수 있었다! 

 

 

 

 

 


 

 

References 

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

 

Window: postMessage() method - Web APIs | MDN

The window.postMessage() method safely enables cross-origin communication between Window objects; e.g., between a page and a pop-up that it spawned, or between a page and an iframe embedded within it.

developer.mozilla.org

 

https://m.blog.naver.com/hyoun1202/221932249560

 

서로 다른 도메인간(Cross-Origin) 통신하기-Cross Document Messaging API 사용예

Cross Document Messaging API를 이용하면 Cross-Origin간 메세지 송수신이 가능하다. iframe에 포...

blog.naver.com