[개발/JS] 다른 모듈의 팝업을 호출하여 발생한 Cross-Origin 문제 해결과정 - postMessage()
✅ 문제상황
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
https://m.blog.naver.com/hyoun1202/221932249560