Chrome扩展程序:从后台向已注入的脚本发送消息

时间:2013-06-29 09:46:39

标签: javascript google-chrome-extension xmlhttprequest message-passing

我目前正在玩Chrome扩展程序,无法找到一个方便的解决方案,可以从后台上下文(让我们称之为 BG )向注入脚本的上下文发送消息(让称之为 INJ )。将消息从 INJ 发送到 BG 就像魅力一样。但是我希望 BG 执行XMLHttpRequest这可能需要一些时间,所以我想将此请求的评估发送到 INJ

不幸的是,我不允许在 INJ 的上下文中注册一个监听器。因此,我能想到的最佳解决方案包括:

  • INJ BG 发送消息,触发XMLHttpRequest
  • 请求一返回 BG 就会在本地存储请求的结果
  • INJ 重复向 BG 发送更多消息,询问结果,除非 BG 回答结果。

也许是这样的:

INJ

function whaitForResult ()
{
  chrome.runtime.sendMessage ({method: "getResult"}, function (response)
  {
    if (response.finished === "true")
      // request finished, lets go on
    else
      setTimeout(whaitForResult, 100);
  }
}
chrome.runtime.sendMessage({method : "triggerRequest"}, function(response) {});
whaitForResult ();

BG

chrome.runtime.onMessage.addListener (function(request, sender, sendResponse)
{
  if (request.method == "triggerRequest")
  {
    // startXMLHttpRequest ();
    sendResponse ({});
    return true;
  }
  else if (request.method == "getResult")
  {
    if (finishedXMLHttpRequest ())
      sendResponse ({finished:"true", result: resultFromXMLHttpRequest ()});
    else
      sendResponse ({finished:"false"});
    return true;
  }
});

我想这应该有用,但在我看来这很麻烦。所以我的问题是:是否有方便的方式将邮件发送到注入的脚本?

如果我的扩展的概念是废话,请提出替代方案。但要执行XMLHttpRequest我需要localStorage中的一些变量,因为这些数据非常敏感,所以我不想将这些变量传递给 INJ 的上下文。因此,在 INJ 中执行XMLHttpRequest不是一种选择。

1 个答案:

答案 0 :(得分:4)

在继续之前,我想指出你只是在处理普通的内容脚本,而不是“注入的脚本”(根据my definition)。

请勿在第一次请求时发送回复(sendResponse({}))。相反,请在响应完成后调用sendResponse

// Content script
chrome.runtime.sendMessage({method: "getResultForRequest"}, function(response) {

});
// Background page
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
    if (request.method == "getResultForRequest") {
        $.ajax({success: sendResponse}); // Example
        return true;
    }
});

正如本答案的顶部所说,您所处理的不是注入脚本,而是内容脚本。 script execution environment of the content script和页面严格分开,因此页面无法读取变量。换句话说,你的前提是有缺陷的;将凭证从后台页面传递到内容脚本是可以的。

我建议不要使用localStorage,而应使用chrome.storage API。此异步API允许内容脚本直接读取扩展存储的持久变量。因此,您不再需要背景或事件页面。有关更详细的比较和示例,请参阅this answer

注意:有两种情况让背景页面处理XHR是有意义的:

  • 页面的内容安全策略会阻止目标网址(此affects Chrome extensions
  • 当前页面通过https提供,而请求的资源通过http提供。混合http和https将改变挂锁的外观,如果可能,应该避免使用。

但是否则,我建议使用chrome.storage API并在内容脚本中执行跨源http请求。