Chrome扩展程序消息传递:未发送响应

我试图在内容脚本和扩展之间传递消息

这是我在内容脚本中的内容

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})
    }
  });

}

现在,如果我在getUrls函数中的ajax调用之前发送响应,则响应会成功发送,但在发送响应时它不会发送响应的ajax调用的成功方法中,当我进入调试时,可以看到该端口在sendResponse函数的代码内为空。


chrome.runtime.onMessage.addListener的文档:

当事件监听器返回时,这个函数变得无效,除非你从事件​​监听器返回true以表示你希望异步发送一个响应(这将保持消息通道对另一端开放,直到调用sendResponse为止)。

所以你只需要添加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方式使用Firefox方式进行此项工作,无需回拨。

您的代码将如下所示:

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 }); });
}) );
链接地址: http://www.djcxy.com/p/16191.html

上一篇: Chrome Extension Message passing: response not sent

下一篇: google chrome extension :: console.log() from background page?