본문 바로가기
WEB/Chrome Extension

[Chrome Extension] content scripts와 popup간 통신하기 - 4

by IT황구 2023. 12. 4.
728x90
반응형

2023.12.03 - [WEB/Chrome Extension] - [Chrome Extension] content scripts를 이용해 DOM 조작하기 - 3

 

[Chrome Extension] content scripts를 이용해 DOM 조작하기 - 3

2023.11.28 - [WEB/Chrome Extension] - [Chrome Extension] 데이터 저장하기, storage api - 2 [Chrome Extension] 데이터 저장하기, storage api - 2 2023.11.26 - [WEB/Chrome Extension] - [Chrome Extension] popup 만들기, 로컬 테스트, 디버

rbals0445.tistory.com

 

지난 3편과 이어집니다.

 

content scripts를 이용해서 현재 보고있는 탭의 DOM을 조작하는데 성공했습니다.

 

이번에는 popup의 액션에 따라 content scripts 안에 선언된 Map의 값을 실시간으로 변경하고 싶었습니다. 따라서 popup과 content scripts 사이에 통신 하는 방법을 찾아봤습니다.

 

꼭 공식문서도 블로그 글을 읽고 보셨으면 좋겠습니다.

 

자세한 내용은 다 담겨있고, 이 글에서는 원하는 기능만을 뽑아서 설명한 것입니다.

 

https://developer.chrome.com/docs/extensions/mv3/messaging/

 

Chrome Extensions Message passing - Chrome for Developers

How to pass messages between extensions and content scripts.

developer.chrome.com

 

popup과 content scripts는 message를 통해서 통신합니다.

 

통신 종류에는 두가지가 있습니다.

  • 일회성 요청
  • 재사용 가능한 long-lived connection

여기서는 popup에서 content scripts로 notify만 해주면 되므로 일회성 요청에 대해 확인합니다.

popup -> content scripts

popup에서 content scripts로 메세지를 보내기 위해서는 `chrome.tabs.sendMessage` 를 이용해서 메세지를 보낼 수 있습니다.

 

예시를 보겠습니다.

key, value를 extension local storage에 저장하고, 모든 탭의 content scripts에 업데이트가 되었다고 notify 하는 예제입니다.

 

// popup.js

function saveTextToStorage($input, $output) {
  const input = $input.value;
  const output = $output.value;

  setChromeLocalStorage(input, output)
    .then(() => {
      clearText([$input, $output]);
      blinkNotice("save success!");

      chrome.tabs.query({}, function (tabs) {
        tabs.forEach((tab) => {
          chrome.tabs.sendMessage(tab.id, {
            command: "updateMap",
            key: input,
            value: output,
          });
        });
      });
    })
    .catch(() => {
      blinkNotice("save failed. due to text limit (10MB)", true);
    });
}

 

 

tabId와 함께 업데이트 내용을 object에 담아서 두번째 인자로 넘겼습니다.

 

content scripts -> popup

content scripts에서 응답을 받고 다시 popup으로 메세지를 보내려면 어떻게 할까요?

 

chrome.runtime.onMessage를 통해서 값을 받을 수 있습니다.

//contentscripts.js

chrome.runtime.onMessage.addListener(function (request,sender,sendResponse) {
  const { key, value, command } = request || {};

  if (command === "updateMap") {
    userDefinedTextMap[key] = value;
  }
  
  sendResponse('잘 받았어!');
});

init();

 

sendMessage를 통해서 보냈던 값을 request 매개변수에서 받았습니다. 이제 sendReponse를 통해서 값을 되돌려 줍니다.

 

여기서 sendResponse를 통해 보낸 값은 popup에서 callback을 통해 받을 수 있습니다.

chrome.tabs.query({}, function (tabs) {
        tabs.forEach((tab) => {
          chrome.tabs.sendMessage(
            tab.id,
            {
              command: "updateMap",
              key: input,
              value: output,
            },
            // 여기 callback에서 받습니다.
            (res) => { 
              if (res) {
                console.log(res);
              }
            }
          );
        });
      });

 

마무리

직접 적용해보니 왜 일회성 요청으로 불리는지 이해되었습니다.

 

popup -> content scripts -> popup 으로 메세지 핑퐁 이후 끝이 납니다.

 

이 방법을 통해서 popup에서 content scripts에 업데이트를 알릴 수 있게 되었고, content scripts에 있는 Map을 바로 업데이트 할 수 있었습니다.

 

원하는 기능은 모두 마무리 된 것 같습니다.  전체 코드는 아래 레포지토리에서 확인할 수 있습니다.

 

추가적인 기능들은 chrome extension docs에서 찾아보시는걸 추천드립니다. (가장 정확합니다)

 

감사합니다

 

https://github.com/rbals0445/Github-Text-Replacer

 

GitHub - rbals0445/Github-Text-Replacer

Contribute to rbals0445/Github-Text-Replacer development by creating an account on GitHub.

github.com

728x90
반응형