Chrome扩展消息未发送响应(未定义)

5cnsuln7  于 2022-12-16  发布在  Go
关注(0)|答案(5)|浏览(172)

**供以后参考:**我通过将onMessage/sendMessage分别切换到后台脚本和内容脚本来解决这个问题。我不知道为什么会这样,但确实如此。

我在过去的三个小时里一直在调试这个问题--我正在构建一个chrome扩展,我发送的消息的响应是“undefined”,我正在尝试获取用户所在标签页的文本,并用它来做一些分析。
内容脚本:

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) {
        if (request.method == "collectText") {
            sendResponse({data: document.body.innerText, method: "collectText"});
        }
        return true;
    }
);

弹出脚本:

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
  chrome.tabs.sendMessage(tabs[0].id, {method: "collectText"}, function(response) {
      if (response) {
        txt = response.data;
        console.log("response arrived");
        console.log(txt);
      } else {
        console.log("No response.");
      }
  });
});

console.logs当前在那里,以便我知道数据是否返回(它不是--每次脚本运行时都会记录“无响应”,并且txt最后未定义)。我不知道为什么这不起作用(我已经尝试了许多相同脚本的变化,但没有效果)。我没有得到任何错误,无论是在扩展的控制台或我的页面。我应该使用后台脚本而不是在popup.js中编写所有内容吗?
谢谢大家!

jdgnovmf

jdgnovmf1#

如果异步返回一个答案,就可能发生这种类型的错误。(尽管在您给出的示例中不会发生这种情况)

// sender
runtime.sendMessage(msg, response => {
  if (!response)
    console.error("This was a fiasco :", runtime.lastError.message);
});

// receiver
runtime.onMessage.addListener(async (request, sender, sendResponse) => {
  var response = await answer_something(request);
  sendResponse(response);
});

// same problem for this receiver
runtime.onMessage.addListener((request, sender, sendResponse) => {
  promise_something(request).then(response => {
    sendResponse(response);
  });
});

在这种情况下,您将看到以下错误:第一个月
若要修复此问题,必须从异步onMessage侦听器返回true。请注意,返回承诺在chrome上不起作用(chrome的docs,docs for firefox)。

busg9geu

busg9geu2#

由于代码+注解,您可能会得到一个错误:

// According to the documentation of chrome.runtime.sendMessage, the
// callback is invoked without any arguments when an error occurs

您需要检查lastError属性以获取有关错误的信息并修复该错误。
霍普,那会有帮助的

vql8enpb

vql8enpb3#

供日后参考:我通过将onMessage/sendMessage分别切换到后台脚本和内容脚本来解决这个问题。我不知道为什么这样做会起作用,但它确实起作用了。

qojgxg4l

qojgxg4l4#

这个问题的解决方案是移动脚本的内容,以便侦听器位于后台脚本中,而消息从内容脚本发送。
与内容脚本通信的弹出窗口不会实现您想要的。

目视检查:

之前,不工作:
弹出脚本----(消息)---〉内容脚本
工作后:
内容脚本----(消息)---〉背景脚本
我看到OP自己的答案上有一条评论说“我希望我知道你的意思”,有2个赞成票!所以我贴出了自己的答案,既直观地展示了OP问题的解决方案,又回答了评论员和2个赞成票的问题。这是一个你投票删除“因为它没有回答问题”的答案吗?我已经在我这边测试过了,它很有效。

6ovsh4lw

6ovsh4lw5#

对我来说,问题是侦听器函数是async。我只想使用await,但这会导致侦听器返回Promise而不是true。您需要将处理程序 Package 在异步函数中。
之前(不正确):

chrome.runtime.onMessage.addListener(async function (request: any, sender, sendResponse) {
  debug('Got message', request);
  if (request.type === 'updateUser') {
    const responseUser = await getUser();
    user = responseUser;
    await chrome.storage.local.set({ user });
    sendResponse({ user });
  }

  return true;
})

之后:

const handleUpdateUser = async (sendResponse: (response: any) => void) => {
  const responseUser = await getUser();
  user = responseUser;
  await chrome.storage.local.set({ user });
  sendResponse({ user });
};

chrome.runtime.onMessage.addListener(function (request: any, sender, sendResponse) {
  debug('Got message', request);

  if (request.type === 'updateUser') {
    handleUpdateUser(sendResponse);
  }
  
  return true;
})

相关问题