[CORS] iframe 부모-자식 간 함수호출

Yoen-ik Jo (여니기)·2020년 11월 16일
2

❗️이슈발생

며칠 전에 있었던 [Vue.js] 외부 자바스크립트에서 Vue Component method 호출하기 이슈를 해결한 뒤 이어서 작업하던 중, 이번엔 상호 함수호출 중 CORS 이슈가 터졌다.

포털을 구성하는 Vue.js 파일이 업로드 될 도메인과 longview 템플릿이 업로드 될 도메인이 달라서 상투적인 방법의 frame 간 함수호출이 불가능했고, 각 도메인이 공통으로 공유하는 부분도 없기 때문에 공통 도메인 처리로 해결도 불가능했다.

Window.postMessage()

[MDN web docs] Window.postMessage()

이번에도 window 전역 객체를 이용해 해결할 수 있었다.

자식창 > 부모창

먼저 자식창에서 부모창의 함수를 호출하기 위해서 데이터를 전달해야 한다.
( iframe 내부에 호출될 document 내에 해당 코드가 포함되어 있어야함 )

// 자식창에서 부모창으로 함수 호출 ( 데이터 전달 )
window.parent.postMessage(
    // 전달할 data (부모창에서 호출할 함수명)
    { functionName : 'test' }
    // 부모창의 도메인
    // , 'http://abc.com'
    // 모든 도메인에 대하여 허용 ( 추천하지 않음 )
    , '*' 
);

자식창으로부터 전달된 데이터를 받기 위해선

window.addEventListener( 'message', (e) => {
    // 전달 된 데이터 
    console.log( e.data.functionName );
  
    // 부모창의 함수 실행
    if( e.data.functionName === 'test' )
      ...
});

부모창 > 자식창

다음으로 부모창에서 자식창의 함수를 호출하기 위해선

const frame = document.getElementById("testIframe").contentWindow;
frame.postMessage(
   {
      functionName : 'testCallback',
      // 파라미터 전달을 위함
      // 위의 자식창 > 부모창에서도 동일하게 사용 가능
      params: [ '1', '2', '3' ]
   }, '*' );

마지막으로 자식창에서 전달받은 데이터를 처리하는 코드이다.

window.addEventListener( 'message', (e) => {
    if( e.data.functionName )
      	// 전달받은 데이터를 명칭으로 하는 함수를 실행시킨다.
        window[e.data.functionName](
          // 파라미터를 가변인자로 전달
          ...e.data.params
        );
});

// 실행될 함수
function testCallback( a, b, c ) {
    console.log( "call", a, b, c );
}

예쁘게 정리해두고 싶어서 메모삼아 포스팅 끄적끄적

참고(CORS) : https://junspapa-itdev.tistory.com/55
참고(문자열로 함수 호출) : https://stackoverflow.com/q/359788

profile
배워가는 초보개발자

0개의 댓글

관련 채용 정보