브라우저 탭간 통신하는 3가지 방법

2024. 8. 2. 14:10·프론트엔드/JavaScript, TypeScript

챗 지피티로 작성해봤다. 나보다 더 잘 쓰는 것 같다.

웹 애플리케이션 개발에서 여러 브라우저 탭 간의 통신은 매우 중요한 요소입니다. 사용자 경험을 향상시키고 실시간 데이터를 동기화하는 데 필수적입니다. 오늘은 브라우저 탭 간 통신을 위한 세 가지 방법인 broadcastMessage, window.postMessage, 그리고 storage 이벤트에 대해 살펴보겠습니다.

1. broadcastMessage의 이해

1.1. broadcastMessage란?

broadcastMessage는 여러 탭 또는 윈도우 간에 메시지를 전송할 수 있는 API입니다. 이 방법은 동일한 출처의 모든 탭에 메시지를 전달할 수 있어 실시간 업데이트가 필요한 애플리케이션에서 유용하게 사용됩니다.

1.2. 사용 예시

사용자가 한 탭에서 특정 작업을 수행했을 때 다른 탭에 그 결과를 실시간으로 반영하고 싶을 때 broadcastMessage를 사용할 수 있습니다.

코드 예시

// app/broadcast.js

'use client';

import { useEffect, useState } from 'react';

const BroadcastComponent = () => {
    const [message, setMessage] = useState('');

    useEffect(() => {
        const channel = new BroadcastChannel('my_channel');

        channel.onmessage = (event) => {
            setMessage(event.data);
        };

        return () => {
            channel.close();
        };
    }, []);

    const sendMessage = () => {
        const channel = new BroadcastChannel('my_channel');
        channel.postMessage('안녕하세요, 다른 탭!');
    };

    return (
        <div>
            <h2>받은 메시지: {message}</h2>
            <button onClick={sendMessage}>메시지 보내기</button>
        </div>
    );
};

export default BroadcastComponent;

2. window.postMessage의 이해

2.1. window.postMessage란?

window.postMessage는 서로 다른 출처(origin)의 윈도우 간에 안전하게 데이터를 전송할 수 있는 방법입니다. 이 API는 프레임, 팝업, 탭 간에 메시지를 주고받을 수 있도록 해줍니다.

2.2. 사용 예시

부모 창과 자식 프레임 간의 통신이 필요할 때 window.postMessage를 활용할 수 있습니다.

부모 창 코드 예시

// app/parent.js

'use client';

const ParentComponent = () => {
    const sendMessage = () => {
        const iframe = document.getElementById('myIframe');
        iframe.contentWindow.postMessage('안녕하세요, 자식 프레임!', '*');
    };

    const handleMessage = (event) => {
        console.log('받은 메시지:', event.data);
    };

    useEffect(() => {
        window.addEventListener('message', handleMessage);
        return () => {
            window.removeEventListener('message', handleMessage);
        };
    }, []);

    return (
        <div>
            <iframe id="myIframe" src="/child" style={{ width: '100%', height: '300px' }}></iframe>
            <button onClick={sendMessage}>자식 프레임에 메시지 보내기</button>
        </div>
    );
};

export default ParentComponent;

자식 프레임 코드 예시

// app/child/page.js

'use client';

import { useEffect } from 'react';

const ChildComponent = () => {
    useEffect(() => {
        const handleMessage = (event) => {
            console.log('부모 창에서 받은 메시지:', event.data);
            event.source.postMessage('안녕하세요, 부모 창!', event.origin);
        };

        window.addEventListener('message', handleMessage);
        return () => {
            window.removeEventListener('message', handleMessage);
        };
    }, []);

    return <div>자식 프레임입니다.</div>;
};

export default ChildComponent;

3. storage 이벤트를 통한 통신

3.1. storage 이벤트란?

storage 이벤트는 로컬 스토리지(localStorage)나 세션 스토리지(sessionStorage)에 데이터가 변경될 때 발생하는 이벤트입니다. 이를 활용하여 동일한 출처의 여러 탭 간에 데이터를 동기화할 수 있습니다.

3.2. 사용 예시

한 탭에서 로컬 스토리지의 값을 변경하면, 다른 탭에서 해당 값을 실시간으로 감지하고 UI를 업데이트할 수 있습니다.

코드 예시

// app/storage.js

'use client';

import { useEffect, useState } from 'react';

const StorageComponent = () => {
    const [storedValue, setStoredValue] = useState('');

    useEffect(() => {
        const handleStorageChange = (event) => {
            if (event.key === 'myData') {
                setStoredValue(event.newValue);
            }
        };

        window.addEventListener('storage', handleStorageChange);
        return () => {
            window.removeEventListener('storage', handleStorageChange);
        };
    }, []);

    const updateStorage = () => {
        const value = document.getElementById('storageInput').value;
        localStorage.setItem('myData', value);
    };

    return (
        <div>
            <input type="text" id="storageInput" placeholder="로컬 스토리지에 저장할 값" />
            <button onClick={updateStorage}>저장하기</button>
            <h3>로컬 스토리지 값: {storedValue}</h3>
        </div>
    );
};

export default StorageComponent;

4. 결론

브라우저 탭 간 통신은 사용자 경험을 극대화하는 데 중요한 역할을 합니다. broadcastMessage는 동일 출처의 모든 탭에 효율적으로 메시지를 전송할 수 있는 반면, window.postMessage는 서로 다른 출처 간의 안전한 데이터 전송을 가능하게 합니다. 마지막으로, storage 이벤트는 동일 출처의 여러 탭 간에 로컬 스토리지 데이터를 동기화하는 유용한 방법입니다.

각 방법의 특성과 장단점을 이해하고, 상황에 맞는 방법을 선택하여 활용하는 것이 중요합니다. 이러한 통신 방법을 적절히 활용하면, 더욱 매끄럽고 인터랙티브한 웹 애플리케이션을 개발할 수 있습니다.

저작자표시 (새창열림)

'프론트엔드 > JavaScript, TypeScript' 카테고리의 다른 글

CJS와 ESM  (0) 2025.01.12
동시 여러 개의 토큰 리프레시 요청 관리하기  (0) 2024.07.28
Typescript와 Duck typing  (0) 2023.12.11
조건부 타입과 맵드 타입, 유틸리티 타입  (1) 2023.03.15
타입 가드  (1) 2023.01.25
'프론트엔드/JavaScript, TypeScript' 카테고리의 다른 글
  • CJS와 ESM
  • 동시 여러 개의 토큰 리프레시 요청 관리하기
  • Typescript와 Duck typing
  • 조건부 타입과 맵드 타입, 유틸리티 타입
정현우12
정현우12
  • 정현우12
    정현우의 개발 블로그
    정현우12
  • 전체
    오늘
    어제
    • 분류 전체보기 (79)
      • 프론트엔드 (56)
        • JavaScript, TypeScript (12)
        • 스타일링 (1)
        • React (13)
        • Next.js (4)
        • 개발 환경 (9)
        • 테스트 (3)
        • 성능 최적화 (11)
        • 함수형 프로그래밍 (2)
        • 구조 (1)
      • 프로젝트 회고 (23)
        • 이미지편집기 개발 (7)
        • 엑셀 다운로드, 업로드 공통 모듈 개발 (4)
        • 사용자 매뉴얼 사이트 개발 (3)
        • 통계자동화 솔루션 개발 (1)
        • 엑셀 편집기 개발 (5)
        • API 플랫폼 (1)
        • 콜센터 솔루션 OB 캠페인 (1)
        • AI 스튜디오 (1)
      • 백엔드 (0)
  • 블로그 메뉴

    • 홈
    • 포트폴리오
    • 태그
  • 인기 글

  • 태그

    React
    React-boilerplate
    useReducer
    Github Actions
    이미지 편집기
    렌더링 성능 최적화
    엑셀 에디터
    webpack
    웹 성능 최적화
    엑셀
    사용자 매뉴얼 사이트
    frontend
    로딩 성능 최적화
    커스텀 훅
    회고
    라이브러리 선정
    memoization
    Next.js
    TypeScript
    JavaScript
  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
정현우12
브라우저 탭간 통신하는 3가지 방법
상단으로

티스토리툴바