며칠 전에 있었던 [Vue.js] 외부 자바스크립트에서 Vue Component method 호출하기 이슈를 해결한 뒤 이어서 작업하던 중, 이번엔 상호 함수호출 중 CORS 이슈가 터졌다.
포털을 구성하는 Vue.js 파일이 업로드 될 도메인과 longview 템플릿이 업로드 될 도메인이 달라서 상투적인 방법의 frame 간 함수호출이 불가능했고, 각 도메인이 공통으로 공유하는 부분도 없기 때문에 공통 도메인 처리로 해결도 불가능했다.
이번에도 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