Computer/WEB, PHP-JAVA-Script
Updated: 2025. 9. 3. 13:41
hwaya.
iframe 불러오는 창 크기에 맞춰서 크기 조절하기
반응형
웹사이트 개발을 의뢰했더니, iframe 외부페이지를 가져오는데 높이를 픽스 시켜두고 답을 안줘서 스크립트로 문제를 해결하였다.
iframe로 불러와지는 페이지에서(편하게 자식) '내 페이지의 높이가 몇 이다' 라고 보내면 받아서 iframe의 높이를 맞춰준다.
index (iframe으로 다른 페이지를 불러오는 페이지, 부모)
아래 스크립트를 </body> 바로 위에, 그러니깐 body의 가장 아래쪽에 넣기.
<script>
// 이 함수는 아이프레임을 찾으면 통신을 준비.
function setupIframeListener(iframe) {
console.log('iframe을 감지하여 리스너를 추가하고 준비 신호를 보냅니다.');
// 자식에게 "준비됐다"는 신호를 보냄
iframe.contentWindow.postMessage('ready-for-message', '*');
// 메시지 리스너는 한번만 추가해야 하므로, 이미 추가되었는지 확인.
if (!window.hasIframeListener) {
window.addEventListener('message', function (event) {
// 메시지가 올 때마다 최신 iframe 요소를 다시 찾음.
const currentIframe = document.getElementById('ifm');
if (currentIframe && event.source === currentIframe.contentWindow) {
if (event.data && event.data.frameHeight) {
currentIframe.style.height = event.data.frameHeight + 'px';
}
}
}, false);
// 리스너가 중복으로 추가되는 것을 방지하기 위한 플래그
window.hasIframeListener = true;
}
}
// 모든 변화를 감시
const observer = new MutationObserver(function(mutations) {
// 페이지에 변화가 생길 때마다 실행.
for (const mutation of mutations) {
// 추가된 노드(요소)가 있는지 확인.
if (mutation.addedNodes.length > 0) {
const iframe = document.getElementById('ifm');
// 만약 추가된 노드 중에 아이프레임이 있다면,
if (iframe) {
// 통신 준비 함수를 실행하고, 파수꾼의 역할을 잠시 중단할 수 있습니다.
setupIframeListener(iframe);
// observer.disconnect(); // 필요에 따라 감시 중단
return; // 아이프레임을 찾았으므로 더 이상 확인할 필요 없음
}
}
}
});
// 페이지 로딩이 끝나면 body 전체를 대상으로 감시를 시작.
window.addEventListener('load', function() {
// 혹시 페이지에 처음부터 아이프레임이 있을 경우를 대비해 한번 실행
const initialIframe = document.getElementById('ifm');
if (initialIframe) {
setupIframeListener(initialIframe);
}
// body에 자식 요소가 추가되거나 제거되는 모든 변화를 감시
observer.observe(document.body, {
childList: true,
subtree: true
});
});
</script>
target (iframe으로 불러올 페이지, 자식)
동일하게, </body> 태그 바로 위에 그러니까 body 마지막에 넣어준다.
<script>
let lastHeight = 0;
function resizeParentFrame() {
const body = document.body;
const html = document.documentElement;
const height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
if (Math.abs(height - lastHeight) > 1) {
console.log('높이가 변경되어 부모에게 전송:', height);
window.parent.postMessage({ frameHeight: height }, '*');
lastHeight = height;
}
}
window.addEventListener('message', function (event) {
if (event.data === 'ready-for-message') {
console.log('부모가 준비되었다는 신호를 받음. 높이를 전송합니다.');
lastHeight = 0;
resizeParentFrame(); // 첫 높이 전송
}
});
window.addEventListener('resize', resizeParentFrame);
const observer = new MutationObserver(function (mutations) {
resizeParentFrame();
});
observer.observe(document.body, { childList: true, attributes: true, subtree: true, characterData: true });
</script>
그럼 왜 이렇게 했을까?
기본 원칙: Same-Origin Policy (동일 출처 정책)
원래 웹 브라우저는 매우 엄격한 보안 규칙인 '동일 출처 정책(Same-Origin Policy)'을 따릅니다.
- 정의: 서로 다른 '출처'(웹사이트 주소)를 가진 페이지끼리는 보안을 위해 서로의 내용에 직접 접근하거나 조작할 수 없다는 규칙입니다.
- 비유: 아파트의 각 집(웹 페이지)은 서로의 사생활(데이터)을 보호하기 위해 문을 잠그고 있습니다. 옆집 사람이 우리 집에 마음대로 들어와 가구를 옮길 수 없는 것과 같습니다.
- 우리의 경우: 부모 창(index.html)과 자식 창(data_annotation.html)은 서로 다른 문서이므로, 이 규칙에 따라 부모가 자식의 높이를 직접 알아내거나, 자식이 부모의 <iframe> 태그를 직접 조작하는 것이 원칙적으로 불가능합니다.
해결책: postMessage라는 안전한 시스템
이러한 불편함을 해결하기 위해, 웹 브라우저는 postMessage라는 특별한 통신 방법을 제공합니다. 이것은 마치 아파트 단지 내에서 사용하는 안전한 내부 우편 시스템과 같습니다.
- 역할: 서로 다른 창(부모-자식, 탭-팝업 등)이 서로에게 안전하게 문자 메시지를 주고받을 수 있게 해주는 통로입니다.
- 보안: 직접 집 안으로 들어가는 대신, 정해진 우편함으로 편지를 보내는 방식이라 안전합니다. 다른 집의 내용물을 훔쳐볼 수는 없고 오직 메시지만 전달 가능합니다.
반응형
'Computer > WEB, PHP-JAVA-Script' 카테고리의 다른 글
웹페이지 들어왔을때 다른곳으로 이동시키기 (0) | 2025.03.10 |
---|---|
이미지 회색으로 필터 씌우기 (0) | 2024.11.15 |
<iframe> 아이프레임 스크롤 기준으로 높이 자동 조절 (0) | 2024.10.15 |
DOMSubtreeModified 이녀석 알아보자. (0) | 2024.07.31 |
Spring(프레임워크) (0) | 2024.07.22 |
Node.js에서 웹서버 바로 가능한데, Nginx를 사용하는 이유 (0) | 2024.06.03 |
const, var, let (0) | 2023.08.24 |
JS/ 천 단위마다 콤마(,) 자동 생성 (0) | 2022.03.12 |