我目前正在玩Chrome扩展程序,无法找到一个方便的解决方案,可以从后台上下文(让我们称之为 BG )向注入脚本的上下文发送消息(让称之为 INJ )。将消息从 INJ 发送到 BG 就像魅力一样。但是我希望 BG 执行XMLHttpRequest
这可能需要一些时间,所以我想将此请求的评估发送到 INJ 。
不幸的是,我不允许在 INJ 的上下文中注册一个监听器。因此,我能想到的最佳解决方案包括:
XMLHttpRequest
也许是这样的:
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
不是一种选择。
答案 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是有意义的:
但是否则,我建议使用chrome.storage
API并在内容脚本中执行跨源http请求。