将消息从后台脚本发送到内容脚本,然后发送到注入脚本
问题:
尽管尝试将消息从后台页面发送到内容脚本,然后发送到注入脚本,但该过程未能按预期工作。内容脚本无法接收来自后台脚本的消息。
解决方案:
该问题是由内容脚本注入的方式引起的。加载扩展时,它不会自动将内容脚本注入现有选项卡中。仅当创建新选项卡或加载扩展后导航现有选项卡时才会发生注入。
解决方案1:条件脚本注入
确保后台和内容之间的通信脚本,可以采用条件脚本注入。后台脚本可以检查选项卡是否准备好接收消息,并仅在尚未注入的情况下注入内容脚本。
Code:
// Background script
function ensureSendMessage(tabId, message, callback) {
chrome.tabs.sendMessage(tabId, { ping: true }, function (response) {
if (response && response.pong) { // Content script ready
chrome.tabs.sendMessage(tabId, message, callback);
} else { // No listener on the other end
chrome.tabs.executeScript(tabId, { file: "content_script.js" }, function () {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError);
throw Error("Unable to inject script into tab " tabId);
}
// OK, now it's injected and ready
chrome.tabs.sendMessage(tabId, message, callback);
});
}
});
}
内容脚本:
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.ping) {
sendResponse({ pong: true });
return;
}
// Content script action
});
解决方案 2:双重执行预防
另一个解决方案是将内容脚本注入选项卡,但采取措施防止其多次执行。
Code:
// Background script
function ensureSendMessage(tabId, message, callback) {
chrome.tabs.executeScript(tabId, { file: "content_script.js" }, function () {
if (chrome.runtime.lastError) {
console.error(chrome.runtime.lastError);
throw Error("Unable to inject script into tab " tabId);
}
// OK, now it's injected and ready
chrome.tabs.sendMessage(tabId, message, callback);
});
}
内容脚本:
var injected;
if (!injected) {
injected = true;
// Your toplevel code
}
解决方案3:不加区别的脚本注入
最后,您可以选择在扩展初始化时将内容脚本注入到所有选项卡中。仅当您的脚本在多次执行或页面加载后不会干扰自身时,才建议这样做。
代码:
chrome.tabs.query({}, function (tabs) {
for (var i in tabs) {
// Filter by URL if needed
chrome.tabs.executeScript(tabs[i].id, { file: "content_script.js" }, function () {
// Now you can use normal messaging
});
}
});
一旦实现这些解决方案中的任何一个,消息就可以成功地从后台脚本中继到内容脚本,并最终中继到注入的脚本。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3