들어가며
최근 같은 유형의 이슈가 연달아 터졌다.
부모 - 자식 관계에 있는 iframe 또는 팝업 창에서 부모창의 함수를 실행하는 경우 아래와 같은 동일한 현상이 발생하여 이슈 처리 방법에 대해 남겨본다.
원인
부모창과 자식창의 Origin이 다르기 때문이다.
브라우저는 Same-Origin 정책을 취하므로, 스크립트가 다른 Origin으로 접근하지 못하도록 한다.
(부모창과 자식창의 프토토콜, 호스트네임, 포트 번호 동일해야 함)
해결 방법
Window.postMessage() 사용하기
해당 메소드는 Window 오브젝트 간 Cross-Origin 통신을 안전하게 할 수 있도록 한다.
즉, Same-Origin이 아니더라도 통신할 수 있게 한다.
대체로 한 window는 다른 윈도우를 참조할 수 있고, (ex. targetWindow = window.opener), targetWindow.postMessage()를 통해 다른 window에 MessageEvent를 전송할 수 있다.
이를 통해 이벤트를 받는 window에서 사용할 수 있다.
부모창에서 자식창으로 메시지 전송시
targetWindow.postMessage(message, targetOrigin, [transfer]);
// 예시
window.opener.postMessage({data: 'data_to_send'}, 'https://child.abc.net');
message : 다른 window에 보낼 데이터
targetOrigin : targetWindow의 origin 지정. "*" 또는 URI이어야 함.
자식창에서 메시지 받을 때
window.addEventListener("message", receiveMessage);
function receiveMessage(event) {
if (event.origin !== "https://parent.abc.net") return;
// 자식창이 전송한 데이터 확인
console.log(event.data);
// TODO...
}
부모창의 함수를 호출하고 싶다면?
부모창에서 자식창으로 메시지 전송시
window.parent.postMessage(
{
funcName: 'openStudyPlanSurveyResult',
params: ['1', '2', '3']
},
'*'
);
자식창에서 메소드 호출 방법
회사에서 필요한 jQuery, 구식으로 짠다면
$(window).on('message', function({ originalEvent : e }) {
if (e.origin !== "https://parent.abc.net") return;
var data = e.data;
if (!$.isEmptyObject(data) && typeof(window[data.funcName]) === 'function') {
var execFunc = new Function('return ' + data.funcName)();
var param1 = data.params[0];
var param2 = data.params[1];
var param3 = data.params[2];
// 함수 실행
execFunc(param1, param2, param3);
}
});
function openStudyPlanSurveyResult(a, b, c) {
console.log('call', a, b, c);
}
조금 더 모던하게 짠다면
window.addEventListener('message', (e) => {
if (e.origin !== "https://parent.abc.net") return;
if (e.data.funcName) {
// 함수 실행
window[e.data.funcName](
...e.data.params
);
}
});
function openStudyPlanSurveyResult(a, b, c) {
console.log('call', a, b, c);
}
출처
https://developer.mozilla.org/ko/docs/Web/API/Window/postMessage
Window.postMessage() - Web API | MDN
window.postMessage() 메소드는 Window 오브젝트 사이에서 안전하게 cross-origin 통신을 할 수 있게 합니다. 예시로, 페이지와 생성된 팝업 간의 통신이나, 페이지와 페이지 안의 iframe 간의 통신에 사용할
developer.mozilla.org
[CORS] iframe 부모-자식 간 함수호출
며칠 전에 있었던 \[Vue.js] 외부 자바스크립트에서 Vue Component method 호출하기 이슈를 해결한 뒤 이어서 작업하던 중, 이번엔 상호 함수호출 중 CORS 이슈가 터졌다.포털을 구성하는 Vue.js 파일이 업
velog.io
SecurityError: Blocked a frame with origin from accessing a cross-origin frame
I am loading an <iframe> in my HTML page and trying to access the elements within it using JavaScript, but when I try to execute my code, I get the following error: SecurityError: Blocked a ...
stackoverflow.com
https://junspapa-itdev.tistory.com/55
서로 다른 도메인을 사용하는 부모창과 자식창(iframe) 간 데이크 통신하는 방법(크로스도메인, pos
부모창에서 iframe을 이용해서 부모창과 다른 도메인을 가진 자식창을 호출해야 하는 경우가 있습니다. 예를 들면, 내가 만든 홈페이지에 구글 애드센스나, 애드픽 등을 넣는 경우 등이 해당됩니
junspapa-itdev.tistory.com
'프론트엔드 > JavaScript' 카테고리의 다른 글
Scope (0) | 2020.12.26 |
---|