我正在尝试从后台脚本向 chrome 扩展中的内容脚本发送消息。但看起来消息是在内容脚本加载之前发送的?
这是我正常使用扩展程序时遇到的错误:
Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.
这是我的后台脚本,带有
tabs.onUpdated
功能:
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.url) {
console.log(changeInfo.url, tabId)
chrome.tabs.sendMessage(tabId, {
url: changeInfo.url,
type: 'URL_CHANGE'
});
}
});
这是我的内容脚本接收功能:
chrome.runtime.onMessage.addListener((obj, sender, response) => {
console.log('received', obj)
if (obj.type === 'URL_CHANGE') {
console.log('testestsetst')
getAuth()
getUrlType(obj.url)
} else if (obj.type === 'AUTH') {
getAuth()
} else if (obj.type === 'UN-AUTH') {
removeAuth()
}
});
每当我正常运行扩展时,我都看不到内容脚本的输出,并且收到如上所述的错误。但是,当我调试后台脚本并单步执行代码时,我没有收到错误,并且我的内容脚本正确打印了所有内容。这可能是由于页面需要加载造成的吗?如果是这样,我该如何解决这个问题?
通过检查 tab 是否完整并通过 tab 参数发送 url 来解决此问题,如下所示:
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete') {
chrome.tabs.sendMessage(tabId, {
url: tab.url,
type: 'URL_CHANGE'
});
}
});
但看起来消息是在内容脚本加载之前发送的?
是的,完全正确。有时,没有脚本加载到当前活动选项卡中,并且无论您等待选项卡加载多久,Service Worker 的结束消息都不会传递到任何现有的内容脚本。这是一种确保您在有正在运行的内容脚本时发送消息的简单方法:
function sendMessageToActiveTab(message) {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
const activeTab = tabs[0];
if (activeTab && activeTab.url && activeTab.url.startsWith("http")) {
chrome.tabs.sendMessage(activeTab.id, message);
} else {
console.log("No content script is running into the activetab");
}
});
}
为了使事情正常工作,您可能需要编辑startsWith()参数以匹配内容脚本的匹配模式。
background.js
chrome.runtime.onInstalled.addListener(function (details) {
if (details.reason == "install") {
chrome.tabs.create({ url: chrome.runtime.getURL(`onboard-page.html`) }, function (tab) {
chrome.tabs.onUpdated.addListener(function listener(tabId, changeInfo) {
if (tabId === tab.id && changeInfo.status == 'complete') {
chrome.tabs.onUpdated.removeListener(listener)
// Now the tab is ready!
chrome.tabs.sendMessage(tab.id, "hello")
}
});
});
} else if (details.reason == "update") {
}
});
content-script.js
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){
console.log(message)
});