왜 iframe끼리는 DOM을 직접 공유하지 못하는지에 대해 DOM과 iframe를 정리해보았다.
같은 도메인이라면 contentWindow, 다른 도메인이면 postMessage를 사용하면 된다.
1. DOM (Document Object Model) 이란?
DOM은 브라우저가 웹 페이지를 이해하고 조작할 수 있도록 HTML 문서의 구조를 나무(Tree) 형태의 객체로 만든 것입니다.
- 비유하자면: HTML 코드가 집의 '설계도'라면, DOM은 그 설계도를 보고 실제로 지어진 '건물(방, 가구, 문 등의 구조)'입니다.
- 자바스크립트는 이 DOM을 통해 웹 페이지의 글자를 바꾸거나, 요소를 숨기는 등의 동적인 조작을 할 수 있습니다.
- 중요한 점: 브라우저에 로드된 각각의 HTML 파일(웹페이지)은 저마다 독립된 DOM을 하나씩 가집니다. 하나의 페이지만 띄워도 DOM이 생기고, 화면이 여러 개면 각각 따로 DOM이 생깁니다.
2. iframe (Inline Frame) 이란?
iframe은 현재 웹 페이지 안에 또 다른 HTML 페이지를 통째로 쏙 집어넣어 보여주는 태그입니다 (<iframe>).
- 비유하자면: 웹 페이지 안에 작은 모니터(창문)를 하나 더 달아서, 그 안에 완전히 별개의 웹사이트나 문서를 띄워놓는 것과 같습니다. (예: 블로그에 유튜브 영상을 띄울 때 사용)
- iframe의 정체: iframe은 단순히 "다른 HTML 화면(또 다른 DOM 세계)을 내 화면 안에 쏙 집어넣기 위해 쓰는 도구(상자)"일 뿐입니다.
3. "iframe끼리는 DOM을 직접 공유하지 않는다"의 의미
부모 페이지(메인 페이지)와 자식 페이지(iframe 안의 페이지)는 각자 고유의 독립된 DOM을 가지고 따로 놉니다.
따라서 부모가 자식의 DOM을 마음대로 직접 제어할 수 없습니다. 이는 보안과 독립성 때문입니다. 만약 아무 웹사이트나 내 페이지에 iframe으로 들어왔을 때 내 사이트의 DOM(로그인 정보 등)을 마음대로 조작할 수 있다면 엄청난 보안 사고가 발생하기 때문에 브라우저가 원천적으로 차단하는 것입니다.
4. 자식에서 부모로 신호를 보내려면? postMessage
DOM을 직접 공유할 수 없기 때문에, 자식이 부모에게 뭔가 요청하거나 데이터를 전달하려면 postMessage라는 안전한 통신 기능을 사용해야 합니다.
- 비유하자면: 자식이 부모 집 문을 무단으로 따고 들어가는(직접 조작) 대신, 우체통(메시지 전송)에 편지를 넣어 보내고 부모가 그것을 확인해 스스로 처리하는 방식입니다.
💡 예시 소스코드
① 부모 페이지 (index.html)
부모는 자식으로부터 메시지가 오는지 항상 귀를 기울이고(이벤트 리스너) 있어야 합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>부모 페이지</title>
</head>
<body>
<h1>여기는 부모 페이지입니다.</h1>
<p id="parent-text">아직 자식의 메시지를 받지 못했습니다.</p>
<!-- iframe 삽입 -->
<iframe id="my-iframe" src="child.html" width="400" height="200"></iframe>
<script>
// 부모는 자식으로부터 메시지가 날아오기를 기다립니다.
window.addEventListener('message', function(event) {
console.log("자식에게서 온 데이터:", event.data);
// 자식이 보낸 데이터가 "changeText"라면 부모의 DOM을 수정합니다.
if (event.data === "changeText") {
document.getElementById('parent-text').innerText = "자식의 요청을 받아 부모가 텍스트를 바꿨습니다!";
}
});
</script>
</body>
</html>
② 자식 페이지 (child.html - iframe 내부)
자식은 window.parent(부모 창 객체)를 통해 부모에게 메시지를 보냅니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>자식 페이지</title>
</head>
<body style="background-color: #fff9c4;">
<h2>여기는 iframe 안쪽(자식)입니다.</h2>
<button id="send-btn">부모에게 말 걸기</button>
<script>
document.getElementById('send-btn').addEventListener('click', function() {
// window.parent를 통해 부모 창에 메시지 전달
// postMessage("보낼 메시지", "허용할 도메인(*는 전부 허용)")
window.parent.postMessage("changeText", "*");
});
</script>
</body>
</html>
📌 요약
- DOM: HTML 구조가 브라우저에 의해 객체화된 것. HTML 파일마다 하나씩 독립적으로 생김.
- iframe: 내 페이지 안에 다른 HTML 페이지를 띄우는 상자 역할.
- DOM 공유 불가: 보안을 위해 부모와 자식은 서로의 DOM을 직접 조작할 수 없음.
- 해결책 (postMessage): 서로 안전하게 메시지를 주고받기 위해 브라우저가 제공하는 공식 소통 방법.