
JavaScript에서 window.open() 함수를 사용하면 새 창(팝업) 또는 현재 창에 지정한 URL을 열 수 있습니다.
이때 새로 열린 창에서 window.opener 객체를 사용하면 원래 창의 window 객체에 접근할 수 있습니다. 이를 이용하면 새 창과 원래 창 사이에 데이터를 주고받을 수 있습니다.
문제점 및 원인
이번 프로젝트에서도 위 방식으로 외부 서비스를 이용한 본인 인증을 구현했는데, 인증 후 새 창의 window.opener가 null이 되어 원래 창에 인증 결과를 전달할 수 없다는 문제가 발견되었습니다.
디버깅해보니, 새 창이 열린 뒤 본인 인증을 위해 외부 도메인으로 리다이렉트되었다가 인증이 끝난 후 다시 저희 도메인으로 돌아오는 과정에서 window.opener 값이 사라지는 것이 원인이었습니다.
해결 방법
MDN 문서에 따르면 window.open()은 두 번째 인자로 name 값을 받습니다. 이 name이 현재 브라우저에서 이미 사용 중이라면 해당 창에 대한 참조를 반환하고, 그렇지 않으면 해당 name을 가진 새 창을 생성합니다.
이를 이용해 window.opener 값을 확인하고, null인 경우 window.open()으로 원래 창을 다시 찾아 window.opener에 재할당하면 됩니다.
// 원래 창
const url = 'www.test-url.com';
const options = 'width=400,height=600,scrollbar=yes';
// 부모 창의 name 지정
window.name = 'parent';
// 새 창에서 데이터를 받아오게 설정
window.addEventListener("message", receiveMessage, false);
window.open(url, '', options);
...
// 새 창
if(!window.opener){
window.opener = window.open('', 'parent'); // 부모 창의 name을 넣어 window.opener 재할당
}
window.opener.postMessage(...); // 원래 창에 데이터 전송주의할 점은 이 방법은 접근이 허용된 창끼리만 사용할 수 있다는 것입니다. 즉, 새 창과 원래 창이 같은 도메인일 때만 사용할 수 있습니다.
따라서 window.open()을 호출하기 전에, 외부 서비스에서 본인 인증이 끝나면 새 창이 다시 저희 도메인으로 리다이렉트되도록 별도 처리가 필요합니다.
참고자료
Related Posts

WebView 전용 페이지가 외부 브라우저로 열렸을 때의 안내 플로우 처리하기
네이티브 인터페이스가 주입되지 않은 환경으로 진입한 사용자의 경험 저하 문제를, 인터페이스 폴링과 BottomSheet 안내, 플랫폼별 분기로 처리한 과정을 다룹니다.

Vanilla JS 댓글 모듈 자체 개발기
프레임워크 독립적인 Vanilla JS 댓글 모듈을 설계·개발하고 기존에 서비스 중이던 Nuxt 3 프로젝트에 통합한 과정을 다룹니다.

광고 차단 확장 프로그램이 이벤트 배너를 숨긴 이유
이벤트 배너가 특정 사용자에게만 보이지 않는 문제를 추적하며 광고 차단 확장 프로그램의 필터링 메커니즘을 이해하고, CSS 클래스명 변경으로 문제를 해결한 과정을 다룹니다.