开发者问题收集

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

2018-01-05
11309

供将来参考: 我通过将 onMessage/sendMessage 分别切换到后台脚本和内容脚本来解决这个问题。我不确定为什么这样做有效,但确实有效。

过去三个小时我一直在尝试调试这个问题——我正在构建一个 chrome 扩展,并且我发送的消息的响应一直是“未定义”。我试图获取用户所在选项卡的文本并使用它来进行一些分析。

内容脚本:

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 中编写所有内容吗?

谢谢!

3个回答

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

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

在这种情况下,您会看到以下错误: 未经检查的运行时。lastError:在收到响应之前,消息端口已关闭

要修复它,您必须从异步 onMessage 侦听器返回 true 。请注意,返回承诺在 chrome 上不起作用( chrome 文档 firefox 文档 )。

Candide Guevara Marino
2020-04-06

对我来说,问题在于侦听器函数是 async 。我只想使用 await ,但这会导致侦听器返回 Promise 而不是 true 。您需要将处理程序包装在异步函数中。

之前(不正确):

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;
})
kuzdogan
2022-12-12

您可能会收到错误,因为代码 + 注释 :

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

您需要检查 lastError 属性以获取有关错误的信息并进行修复。

希望这会有所帮助。

Sergii Rudenko
2018-01-05