这是我的设置
background.js
var port = null;
function setPort() {
chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
port = chrome.tabs.connect(tabs[0].id, {name: "CONTENTSCRIPT"});
});
}
// when i click on something, get the port and send a message
function clickHandler(e) {
setPort();
if (port) {
port.postMessage({key: 'message', value: true});
}
}
contentscript.js
chrome.runtime.onConnect.addListener(function (port) {
if (port.name == "CONTENTSCRIPT") {
port.onMessage.addListener(function (msg) {
console.log(msg);
});
}
});
我正在做的是点击随机标签上的contextMenu按钮并尝试发送一个meessage。
发生的事情是,我点击的第一个时间,没有任何反应,没有错误。我第二次点击消息就会通过。
如果我切换到另一个标签,然后点击菜单按钮,我会收到Error: Attempting to use a disconnected port object
错误。如果我再次点击该消息将成功发送
我尝试使用var port = chrome.runtime.connect({name: "CONTENTSCRIPT"});
,但每次都出现错误的端口
想法?
答案 0 :(得分:4)
您的问题在于chrome.tabs.query
是异步的。
执行setPort()
,它会在query
执行回调之前立即返回并设置端口。目前,port
为空或指向您之前标签的端口。
因此,您要么没有错误,要么出错,因为旧端口无效。
发生这种情况后,query
中的回调即被执行,并且port
已设置为下次通信。
因此,要解决此问题,您需要在调用链中设置端口后发送消息。例如:
function setPort(callback) {
chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
port = chrome.tabs.connect(tabs[0].id, {name: "CONTENTSCRIPT"});
callback(port);
});
}
function clickHandler(e) {
setPort( function (port) {
if (port) { port.postMessage({key: 'message', value: true}); }
});
}
编辑:顺便说一下,你应该重用一个端口,这就是重点。如果您每次重新建立连接,最好使用sendMessage
,但我认为您只使用上面的代码进行测试。