Javascript

Iframe에서 부모 window와 통신하는 방법 (react, vue <=> iframe)

evan.k 2023. 6. 7. 15:47

서비스를 개발하다보면 간간히 iframe을 사용해야할 일이 발생한다.

가령 도메인이 다른 서비스를 기존 서비스 내에서 보여줘야 한다던지 특정 요소 안에서 외부 서비스를 보여줘야 하는 등 생각보다 사용해야할 일이 많이 생긴다.

서로 다른 도메인을 가지고 있기 때문에 window 객체를 직접 참조하려고 하면 cors에러가 발생하게 된다.

 

그럼 서로 데이터를 공유하거나 통신해야하는 로직이 필요한 경우 어떻게 해야하는가?

 

iframe 내에서 window.parent.postMessage() 메서드를 사용하고 부모 window에서 event handler 메서드를 추가해주면 iframe에서 보내주는 메세지를 부모 window에서 처리할 수 있게 된다.

뒤로가기를 부모 window에서 할 수 있게 처리하는 예시이다.iframe

window.parent.postMessage("back", "*");

부모 window (React)

const CustomIframe = () => {
    useEffect(() => {
        const onMessageListener = ({ data}) => {
			if (data.message === "back") {
            	window.history.back();
			}
        };
        window.addEventListener('message', onMessageListener);

        return () => window.removeEventListener('message', onMessageListener);
      }, []);
      
      return (
      	<iframe
			id="test_id"
        	src="test_url"
        />
      )
  }

부모 window (Vue)

<template>
	<section>
    	<iframe id="test_id" src="test_url" />
	</section>
</template>

<script>
 	export default {
		mounted() {
			window.addEventListener("message", this.receiveMessage);
		},
		destroyed() {
			window.removeEventListener("message", this.receiveMessage);
		},
		methods: {
			receiveMessage(event) {
				if (event.data === "back") {
					window.history.back()
				}
			}
		}
	}
</script>

위의 예시 코드처럼 iframe에서 보내준 message를 부모 window에서 받은 후 해당 로직을 추가해주면 간단히 처리해줄 수 있다.