programing

크롬 확장 메시지 전달: 응답이 전송되지 않음

goodsources 2023. 11. 7. 20:49
반응형

크롬 확장 메시지 전달: 응답이 전송되지 않음

내용 스크립트와 확장자 사이에 메시지를 전달하려고 합니다.

내용 스크립트에 있는 내용은 다음과 같습니다.

chrome.runtime.sendMessage({type: "getUrls"}, function(response) {
  console.log(response)
});

그리고 배경화면에 제가 가지고 있는 것은

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if (request.type == "getUrls"){
      getUrls(request, sender, sendResponse)
    }
});

function getUrls(request, sender, sendResponse){
  var resp = sendResponse;
  $.ajax({
    url: "http://localhost:3000/urls",
    method: 'GET',
    success: function(d){
      resp({urls: d})
    }
  });

}

이제 내가 ajax call 전에 응답을 보내면,getUrls함수, 응답은 성공적으로 전송되지만, 응답을 전송할 때 ajax 호출의 성공 방법에서는 전송되지 않습니다. 디버깅을 시작하면 포트가 코드 내부에 null임을 알 수 있습니다.sendResponse기능.

다음에 대한 설명서에서:

sendResponse()를 비동기적으로 사용하려면 onMessage 이벤트 처리기에 true 반환을 추가합니다.

그래서 당신은 단지 추가하기만 하면 됩니다.return true;에 전화한 후에getUrls응답 함수를 비동기적으로 호출할 것임을 나타냅니다.

다른 설명서(: 설명서)에는 언급되어 있지 않기 때문에 개발자가 이를 놓쳤을 수 있습니다.

합격한 답변이 맞습니다, 단순화한 샘플 코드를 추가하고 싶어서요.문제는 특정 메시지가 비동기로 처리될지 여부를 개발자들에게 알려주기 때문에 (제가 보기에는) API가 잘 설계되어 있지 않다는 것입니다.다양한 메시지를 처리할 경우 전달된 sendResponse 함수가 비동기식으로 불릴지 여부를 알 수 없기 때문에 불가능한 작업이 됩니다.예를 들어 다음과 같습니다.

chrome.extension.onMessage.addListener(function (request, sender, sendResponseParam) {
if (request.method == "method1") {
    handleMethod1(sendResponse);
}

내가 어떻게 알아요 깊은 곳이 있나요?handleMethod1통화가 비동기화됩니까, 아닌가요?어떻게 수정하는 사람이handleMethod1비동기적인 것을 도입함으로써 발신자를 꺾을 것이라는 것을 알고 있습니까?

제 해결책은 다음과 같습니다.

chrome.extension.onMessage.addListener(function (request, sender, sendResponseParam) {

    var responseStatus = { bCalled: false };

    function sendResponse(obj) {  //dummy wrapper to deal with exceptions and detect async
        try {
            sendResponseParam(obj);
        } catch (e) {
            //error handling
        }
        responseStatus.bCalled= true;
    }

    if (request.method == "method1") {
        handleMethod1(sendResponse);
    }
    else if (request.method == "method2") {
        handleMethod2(sendResponse);
    }
    ...

    if (!responseStatus.bCalled) { //if its set, the call wasn't async, else it is.
        return true;
    }

});

이렇게 하면 메시지 처리 방법에 관계없이 반환 값이 자동으로 처리됩니다.이는 응답 함수를 호출하는 것을 잊지 않는 것으로 가정한 것입니다.크롬이 우리를 위해 이것을 자동화했을 수도 있다는 것을 주목하세요. 왜 그들이 하지 않았는지 모르겠습니다.

제 라이브러리인 https://github.com/lawlietmester/webextension 을 사용하면 이것이 콜백 없이 파이어폭스 방식으로 Chrome과 FF 모두에서 작동하도록 만들 수 있습니다.

코드는 다음과 같습니다.

Browser.runtime.onMessage.addListener( request => new Promise( resolve => {
    if( !request || typeof request !== 'object' || request.type !== "getUrls" ) return;

    $.ajax({
        'url': "http://localhost:3000/urls",
        'method': 'GET'
    }).then( urls => { resolve({ urls }); });
}) );

언급URL : https://stackoverflow.com/questions/20077487/chrome-extension-message-passing-response-not-sent

반응형