FRONTMANFRONTMAN
  • 태그
  • 방명록
  • 글쓰기
  • 관리자
  • HOME
  • 태그
  • 방명록
iframe과 통신하는 방법
hahekaku
iframe과 통신하는 방법FE/WEB2025. 2. 3. 15:31@hahekaku
Table of Contents

iframe이란?

iframe(inline frame)은 HTML 문서 내에 다른 HTML 페이지를 삽입할 수 있는 태그입니다. 주로 외부 콘텐츠를 현재 페이지에 표시하거나, 서로 다른 도메인의 콘텐츠를 불러오는 데 사용됩니다.

<iframe src="https://www.example.com" width="600" height="400"></iframe>

위와 같은 코드로 외부 사이트를 현재 페이지에 삽입할 수 있습니다. 그러나 iframe에 삽입된 콘텐츠와 부모 페이지 간에는 보안상의 이유로 직접적으로 JavaScript 객체를 공유할 수 없습니다. 이러한 제약은 특히 서로 다른 출처(origin)를 가진 경우 더 엄격해집니다.


iframe과의 통신 방식

iframe과 부모 페이지 간의 통신을 위해 가장 일반적으로 사용되는 방법은 postMessage API입니다. 이 방법은 서로 다른 출처 간에도 안전하게 메시지를 주고받을 수 있도록 설계되었습니다.

postMessage란?

postMessage는 서로 다른 윈도우 간에 안전하게 메시지를 보낼 수 있는 API입니다. 부모 페이지는 iframe에 메시지를 보내고, iframe은 부모 페이지로부터 메시지를 수신할 수 있습니다.

문법은 다음과 같습니다.

targetWindow.postMessage(message, targetOrigin);
  • targetWindow: 메시지를 보낼 대상 창(iframe의 contentWindow 등).
  • message: 전송할 데이터(문자열 또는 객체).
  • targetOrigin: 메시지를 수신할 창의 출처(origin). 보안 강화를 위해 정확한 출처를 지정하는 것이 중요합니다.

부모 페이지에서 iframe으로 메시지 보내기

부모 페이지 코드

<!-- 부모 페이지 -->
<iframe id="childFrame" src="child.html" width="600" height="400"></iframe>

<button id="sendMessageButton">메시지 보내기</button>

<script>
  const iframe = document.getElementById('childFrame');
  const sendMessageButton = document.getElementById('sendMessageButton');

  sendMessageButton.addEventListener('click', () => {
    const message = { type: 'GREETING', text: '안녕하세요, iframe!' };
    iframe.contentWindow.postMessage(message, 'https://example.com'); // 정확한 출처 지정
  });
</script>
  • iframe 요소를 가져와 contentWindow를 통해 postMessage를 호출합니다.
  • message는 객체 형태로 전송할 수 있으며, type을 활용해 메시지의 유형을 구분할 수 있습니다.
  • targetOrigin은 반드시 iframe의 정확한 출처로 지정해야 보안 사고를 예방할 수 있습니다.

iframe 페이지 코드(child.html)

<!-- child.html -->
<script>
  window.addEventListener('message', (event) => {
    // 보안: 신뢰할 수 있는 출처인지 확인
    if (event.origin !== 'https://parent.com') {
      return;
    }

    const { type, text } = event.data;

    if (type === 'GREETING') {
      console.log('부모로부터 받은 메시지:', text);
    }
  });
</script>
  • message 이벤트를 수신하기 위해 addEventListener로 이벤트 리스너를 등록합니다.
  • event.origin을 확인하여 신뢰할 수 없는 출처의 메시지를 차단합니다.
  • event.data에 전송된 데이터가 담겨 있습니다.

iframe에서 부모 페이지로 메시지 보내기

반대로 iframe에서 부모 페이지로 메시지를 보낼 수도 있습니다. 이때는 parent.postMessage를 사용합니다.

iframe 페이지 코드(child.html)

<button id="sendToParentButton">부모로 메시지 보내기</button>

<script>
  const sendToParentButton = document.getElementById('sendToParentButton');

  sendToParentButton.addEventListener('click', () => {
    const message = { type: 'RESPONSE', text: '안녕하세요, 부모님!' };
    parent.postMessage(message, 'https://parent.com'); // 부모 출처 지정
  });
</script>
  • parent.postMessage를 통해 부모 창으로 메시지를 전송합니다.
  • 보안 강화를 위해 부모 페이지의 정확한 출처를 지정합니다.

부모 페이지 코드

window.addEventListener('message', (event) => {
  if (event.origin !== 'https://example.com') {
    return; // 출처 확인
  }

  const { type, text } = event.data;

  if (type === 'RESPONSE') {
    console.log('iframe으로부터 받은 메시지:', text);
  }
});

postMessage 사용 시 보안 고려 사항

  1. 출처 검증(origin 확인)
    • 반드시 event.origin을 확인하여 신뢰할 수 있는 출처에서 온 메시지만 처리해야 합니다.
    • 예: if (event.origin !== 'https://trusted-site.com') return;
  2. 데이터 검증
    • 수신한 데이터의 구조와 값이 예상한 것인지 검증해야 합니다.
    • 예: if (typeof event.data === 'object' && event.data.type) { ... }
  3. targetOrigin 제한
    • postMessage 호출 시 '*'을 사용하지 말고, 가능한 한 정확한 출처를 지정해야 합니다.
  4. 민감한 데이터 전송 금지
    • 민감한 정보를 메시지로 직접 전송하지 말고, 별도의 보안 메커니즘을 사용해야 합니다.

실전 예제: 부모와 iframe 간의 양방향 채팅

부모 페이지 (index.html)

<iframe id="chatFrame" src="chat.html" width="400" height="300"></iframe>

<div>
  <input type="text" id="parentMessage" placeholder="부모 메시지 입력" />
  <button id="sendToIframe">보내기</button>
</div>

<script>
  const iframe = document.getElementById('chatFrame');
  const messageInput = document.getElementById('parentMessage');
  const sendButton = document.getElementById('sendToIframe');

  sendButton.addEventListener('click', () => {
    const message = messageInput.value;
    iframe.contentWindow.postMessage({ type: 'PARENT_MESSAGE', text: message }, 'https://example.com');
    messageInput.value = '';
  });

  window.addEventListener('message', (event) => {
    if (event.origin !== 'https://example.com') return;

    const { type, text } = event.data;
    if (type === 'IFRAME_MESSAGE') {
      console.log('iframe 메시지:', text);
    }
  });
</script>

iframe 페이지 (chat.html)

<div>
  <input type="text" id="iframeMessage" placeholder="iframe 메시지 입력" />
  <button id="sendToParent">부모로 보내기</button>
</div>

<script>
  const messageInput = document.getElementById('iframeMessage');
  const sendButton = document.getElementById('sendToParent');

  sendButton.addEventListener('click', () => {
    const message = messageInput.value;
    parent.postMessage({ type: 'IFRAME_MESSAGE', text: message }, 'https://parent.com');
    messageInput.value = '';
  });

  window.addEventListener('message', (event) => {
    if (event.origin !== 'https://parent.com') return;

    const { type, text } = event.data;
    if (type === 'PARENT_MESSAGE') {
      console.log('부모 메시지:', text);
    }
  });
</script>

정리

  • iframe과 부모 페이지 간의 통신은 postMessage API를 통해 안전하고 효율적으로 처리할 수 있습니다.
  • 반드시 origin 검증과 데이터 유효성 검사를 통해 보안 위협을 방지해야 합니다.
  • 실시간 데이터 교환, 채팅 기능, 외부 서비스 통합 등 다양한 활용이 가능합니다.

postMessage의 활용 방법과 보안 지침을 잘 숙지하면 복잡한 웹 애플리케이션에서도 안전한 iframe 통신을 구현할 수 있습니다.

 

저작자표시 비영리 동일조건 (새창열림)

'FE > WEB' 카테고리의 다른 글

Web Worker란 무엇인가?  (4) 2025.02.02
URL과 URLSearchParams 활용법  (0) 2025.02.01
MutationObserver란?  (0) 2025.02.01
FE/WEB 추천 글
more
  • Web Worker란 무엇인가?
    Web Worker란 무엇인가?2025.02.02
  • URL과 URLSearchParams 활용법
    URL과 URLSearchParams 활용법2025.02.01
  • MutationObserver란?
    MutationObserver란?2025.02.01
FRONTMAN

검색

250x250

방문자 수

Total
Today
Yesterday

카테고리

  • 분류 전체보기 (54)
    • Language (48)
      • JavaScript (15)
      • TypeScript (14)
      • Python (14)
      • Dart (5)
      • Java (0)
    • FE (6)
      • WEB (4)
      • React (0)
      • Flutter (1)
    • CS (0)
      • Algorithm (0)
      • Network (0)
    • DevOps (0)

공지사항

  • 전체보기

최근 글

인기 글

태그

  • OOP
  • Python
  • Modules
  • inline frame
  • typeScript
  • web
  • list
  • npm
  • JavaScript
  • Interface
  • await
  • function
  • 웹
  • 타입
  • async
  • Object
  • Import
  • 타입스크립트
  • nodejs
  • Flutter
  • Type
  • export
  • 자바스크립트
  • tuple
  • 리스트
  • js
  • frontend
  • DART
  • CLASS
  • 파이썬

최근 댓글

FRONTMAN :: hahekaku
CopyrightBluemivDesigned byBluemiv

티스토리툴바