Chrome Extension 2 편 -- 통신

28974 단어 전단 개발
크롬 확장 2 편 – 통신
크롬 확장 JS 대비
JS 종류
접근 가능 한 API
DOM 접근 상황
JS 액세스 현황
직접 크로스 필드
background js
devtools 시 리 즈 를 제외 한 대부분의 API 에 접근 할 수 있 습 니 다.
직접 접근 불가
안 된다
되다
content scripts
extension, runtime 등 일부 API 에 만 접근 할 수 있 습 니 다.
접근 가능
안 된다
안 된다
browser action
devtools 시 리 즈 를 제외 한 대부분의 API 에 접근 할 수 있 습 니 다.
직접 접근 불가
안 된다
되다
inject script
일반 JS 와 차이 가 없 으 며 확장 API 에 접근 할 수 없습니다.
접근 가능
접근 가능
안 된다
커 뮤 니 케 이 션
content script 확장 프로그램 으로 통신
// content script
chrome.runtime.sendMessage({ greeting: "  " }, function (response) {
    console.log("         :" + response);
});

// background.js    popup.js(browser action)
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    console.log("    content-script   :");
    console.log(request, sender, sendResponse);
    sendResponse("    ,        :" + JSON.stringify(request));
});

메모: 만약 여러 페이지 가 onMessage 사건 을 감청 한다 면, 어떤 사건 에 대해 서 는 sendResponse () 를 처음 호출 하 는 것 만 성공 적 으로 응답 할 수 있 고, 모든 다른 응답 은 무 시 됩 니 다.
콘 텐 츠 script 에 서 는 sendmessage 로 메 시 지 를 보 내 고 수신 자 에 게 runtime. onMessage 나 runtime. onMessage External 을 사용 하여 자신의 확장 프로그램 에 메 시 지 를 보 내 면 수신 자 는 onMessage 를 사용 하 며 다른 확장 프로그램 에 보 내 면 onMessage External 을 사용 합 니 다.
확장 프로그램 이 coentent script 에 메 시 지 를 보 내 는 데 사용 하 는 것 은 tabs. sendmessage 입 니 다.
//                     
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
    chrome.tabs.sendMessage(tabs[0].id, { greeting: "  " }, function (
        response
    ) {
        console.log(response.farewell);
    });
});

주의사항: contentscripts 가 popup 에 자발적으로 메 시 지 를 보 내 는 전 제 는 popup 이 열 려 있어 야 한 다 는 것 입 니 다!그렇지 않 으 면 background 를 이용 하여 중간 회전 을 해 야 합 니 다.background 와 popup 이 동시에 감청 하면 메 시 지 를 동시에 받 을 수 있 지만 한 개 만 sendResponse 를 보 낼 수 있 습 니 다. 한 개 만 먼저 보 내 면 다른 하 나 는 다시 보 내 면 무효 입 니 다.
popup 과 background 의 통신
popup 은 background 의 JS 방법 을 직접 호출 할 수도 있 고 background 의 DOM 에 직접 접근 할 수도 있 습 니 다.
// background.js
function test() {
    alert("  background!");
}

// popup.js
var bg = chrome.extension.getBackgroundPage();
bg.test(); //   bg   
alert(bg.document.body.innerHTML); //   bg DOM

주의: 문법 오류 가 있어 서 는 안 됩 니 다. 그렇지 않 으 면 출력 을 볼 수 없습니다.
background 접근 popup 은 다음 과 같 습 니 다. (전 제 는 popup 이 열 렸 다 는 것 입 니 다)
var views = chrome.extension.getViews({ type: "popup" });
console.log("---views---", views);
if (views.length > 0) {
    console.log(views[0].location.href);
}

디버그 단계:
  • 배경 페이지 를 먼저 열 면 console tab 에서 출력 ---views--- []
  • 확장 을 클릭 하여 팝 업 페이지 팝 업
  • 배경 페이지 의 콘 솔 을 새로 고치 면 출력 내용 을 볼 수 있 습 니 다
  • popup / background 와 content 통신
    // background.js    popup.js
    function sendMessageToContentScript(message, callback) {
        chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
            chrome.tabs.sendMessage(tabs[0].id, message, function (response) {
                if (callback) callback(response);
            });
        });
    }
    sendMessageToContentScript(
        { cmd: "test", value: "  ,  popup!" },
        function (response) {
            console.log("  content   :" + response);
        }
    );
    
    // content script
    chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
        // console.log(sender.tab ?"from a content script:" + sender.tab.url :"from the extension");
        if (request.cmd == "test") alert(request.value);
        sendResponse("        !");
    });
    

    inject script 과 content script 통신
    content - script 과 페이지 내 스 크 립 트 (injected - script 은 당연히 페이지 내 스 크 립 트 에 속 합 니 다) 사이 에서 유일 하 게 공유 하 는 것 은 페이지 의 DOM 요소 입 니 다. 두 가지 방법 으로 양자 통신 을 실현 할 수 있 습 니 다.
  • window. postmessage 와 window. addEventListener 를 통 해 양자 메시지 통신 (추천)
  • 을 실현 할 수 있 습 니 다.
    // inject script
    window.postMessage({ test: "  !" }, "*");
    
    // content script
    window.addEventListener(
        "message",
        function (e) {
            console.log(e.data);
        },
        false
    );
    
  • 사용자 정의 DOM 이 벤트 를 통 해 이 루어 집 니 다.
  • // inject script
    var customEvent = document.createEvent("Event");
    customEvent.initEvent("myCustomEvent", true, true);
    function fireCustomEvent(data) {
        hiddenDiv = document.getElementById("myCustomEventDiv");
        hiddenDiv.innerText = data;
        hiddenDiv.dispatchEvent(customEvent);
    }
    fireCustomEvent("  ,    JS!");
    
    // content script
    var hiddenDiv = document.getElementById("myCustomEventDiv");
    if (!hiddenDiv) {
        hiddenDiv = document.createElement("div");
        hiddenDiv.style.display = "none";
        document.body.appendChild(hiddenDiv);
    }
    hiddenDiv.addEventListener("myCustomEvent", function () {
        var eventData = document.getElementById("myCustomEventDiv").innerText;
        console.log("         :" + eventData);
    });
    

    긴 연결
    위 에서 말 한 것 은 모두 짧 은 연결 에 속 하고 일회 성 이다.
    긴 연결 을 사용 하려 면 runtime. connect 나 tabs. connect 를 사용 하여 콘 텐 츠 스 크 립 트 에서 확장 프로그램 (또는 반대로) 으로 장시간 연결 할 수 있 습 니 다.만 든 채널 은 서로 다른 유형의 연결 을 구분 할 수 있 는 선택 가능 한 이름 을 가 질 수 있 습 니 다.
    연결 을 만 들 때 양쪽 모두 runtime. Port 대상 을 얻 고 연결 을 통 해 메 시 지 를 보 내 고 받 을 수 있 습 니 다.
    content script 에서 연결 을 만 들 고 메 시 지 를 보 내 고 감청 합 니 다.
    var port = chrome.runtime.connect({ name: "  " });
    port.postMessage({ joke: "  " });
    port.onMessage.addListener(function (msg) {
        if (msg.question == "  ?") port.postMessage({ answer: "  " });
        else if (msg.question == "    ?")
            port.postMessage({ answer: "Bovary   " });
    });
    

    수신 단 에서 onConnect 이벤트 감청 을 통 해
    chrome.runtime.onConnect.addListener(function (port) {
        console.assert(port.name == "  ");
        port.onMessage.addListener(function (msg) {
            if (msg.joke == "  ") port.postMessage({ question: "  ?" });
            else if (msg.answer == "  ")
                port.postMessage({ question: "    ?" });
            else if (msg.answer == "Bovary   ")
                port.postMessage({ question: "     。" });
        });
    });
    

    연결 이 언제 닫 히 는 지 알 고 싶 을 수도 있 습 니 다. 예 를 들 어 열 린 포트 마다 상 태 를 따로 유지 해 야 합 니 다.이 경우 runtime. Port. onDisconnect 이 벤트 를 감청 할 수 있 습 니 다. 연 결 된 다른 쪽 에서 runtime. Port. disconnect 를 호출 하거나 이 포트 를 포함 하 는 페이지 가 끝 났 을 때 (예 를 들 어 탭 페이지 가 다른 페이지 로 넘 어 갔 을 때) 포트 마다 이 이벤트 가 발생 할 수 있 습 니 다.
    총결산
  • content script 은 현재 열 린 페이지 에 붙 어 있 기 때문에 background / popup 에 메 시 지 를 보 내 면 runtime. sendmessage 를 직접 보 내 면 됩 니 다
  • bacground / popup 은 각각 확 장 된 배경 페이지 와 확장 전시 페이지 입 니 다. 어느 페이지 (즉 tab) 의 content script 에 메 시 지 를 보 낼 지 모 르 기 때문에 tabs. sendmessage
  • 를 통 해 메 시 지 를 보 냅 니 다.
  • injected script 과 content script 은 모두 페이지 내 스 크 립 트 에 속 합 니 다. content script 은 페이지 자체 의 js 를 가 져 올 수 없 지만 inject script 은 페이지 js 를 가 져 올 수 있 습 니 다. content script 과 inject script 간 에 공유 하 는 것 은 페이지 의 DOM 요소 입 니 다. window 는 페이지 요소 이기 때문에 메 시 지 를 전달 할 수 있 습 니 다
  • background 와 popup 은 모두 자신 을 확장 하 는 js 에 속 하 는데 이 두 가지 통신 은 더욱 간단 하 다.

  • 크롬 확장 통신 데모 가 있 습 니 다. 각각 각종 통신 을 실 행 했 습 니 다. 가 지 를 바 꿔 서 직접 볼 수 있 습 니 다.

    좋은 웹페이지 즐겨찾기