[JavaScript] Window.postMessage()

cocoding·2023년 7월 10일

study

목록 보기
1/3

이슈

휴대폰 인증 기능을 추가하려는데 인증하는 화면은 타회사의 API를 이용하기 때문에 cross-origin 오류가 났다.

cors 오류는 다른 출처에서 응답을 받아오면 발생되는 오류다.
자세한 내용은 다음의 사이트에서 읽고 공부하길 추천한다.
설명이 굉장히 잘 되어 있다.

CORS는 왜 이렇게 우리를 힘들게 하는 걸까?
교차 출처 리소스 공유 (CORS)

발생 이유


이 화면에서 인증 처리를 하기 위해서 사용자가 입력한 데이터를 가지고 와야하는데, 이 때 팝업으로 띄워진 화면이 윈도우와 교차 출처이기 때문에 오류가 발생한 것이다.

해결방법

2가지를 사용했다.

  1. window.open()
  2. postMessage()

window.open()

window.open(url, target, windowFeatures)

  • url
    url은 새 창에 보여지는 주소이며, 비워두면 about:blank가 보인다.

  • name
    새 창의 속성 또는 창의 이름을 지정한다.
    선택적인 값인데 기본값으로는 "_blank"이다.
    속성값으로는 _self, _blank, _parent, _top등이 있다.

  • windowFeatures
    창의 기본 크기 및 최소 팝업 창의 여부 등의 옵션이 포함된다.

이 기능은 최소한 팝업 창을 권장한다. 자세한 사용법이나 특징은 Window: open() method 사이트를 참고하길 바란다.

현재 사용하고 있는 프레임워크는 vue.js 이기 때문에 메서드 안에 다음과 같이 코드를 작성했다.

var auth_popup = "auth_popup"

			var width = 410
			var height = 500

			var leftpos = screen.width / 2 - width / 2
			var toppos = screen.height / 2 - height / 2

			var winopts = "width=" + width + ", height=" + height
			var position = ",left=" + leftpos + ", top=" + toppos
			var form_auth = document.form_auth

			form_auth.target = auth_popup
			form_auth.action = BASE_URL

			var self = this
			function onMessage(event) {
				if (event.data == "close-mobile-cert-popup") {
					self.goToCertMobile()
					window.removeEventListener("message", onMessage)
				}
			}
			window.addEventListener("message", onMessage)
			window.open("", auth_popup, winopts + position)

이 코드는 백엔드에서 close-mobile-cert-popup을 data로 받게 되면 goToCertMobile이라는 메서드를 호출하면서 동시에 onMessage메서드를 제거한다.

close-mobile-cert-popup이라는 data는 백엔드에서 postMessage로 전달되어 온다.

즉, onMessage()함수는 받을 준비를 해놓는 것이다.
다음은 송신측의 코드를 살펴보자.

window.postMessage()

window 객체 사이에서 안전한 cross-origin 통신을 할 수 있도록 도와주는 메서드이다.

window.postMessage(message, targetOrigin, [transfer]);

  • message
    다른 window에 전달할 data를 담는다.

  • targetOrigin
    보낼 url을 작성한다.

  • transger
    메시지와 함께 전달된다.

자세한 내용은 다음의 window.postMessage() 사이트에서 살펴보길 바란다.

jsp파일이었기 때문에 다음과 같은 코드로 작성했다.

window.onload=function()
{
		window.opener.postMessage("close-mobile-cert-popup", '${message를_받는_url}');
		window.close();
}

코드를 jsp파일에서 작성하여 보내면 위에 vue에서 close-mobile-cert-popup 메시지를 받게 되는 것이다.

마무리

설명이 장황하고, 어려운 듯보이나 늘 그렇듯 구현하고 나면 상당히 간단한 문제라고 볼 수 있을 것이다.

postMessage와 window.opener도 마찬가지로 처음엔 생소하지만 간편한 메서드로 cross-origin 문제를 간단히 해결할 수 있다.

이와 같은 이슈로 postMessage, window.opener와 더불어 cross-origin까지 이해하게 됐다.
아직 블로그 작성을 시작한지 얼마 되지 않아 횡설수설하고 정리가 잘 안됐지만,, 이 다음 포스트는 조금 더 수월히 정리되고 이해되는 글이 되도록 해봐야겠다.

0개의 댓글