我正在尝试向新创建/更新的选项卡发送消息并在那里接收它:
var tabAction = 'create'; // tabAction equals *create* or *update*
chrome.tabs[tabAction]({
url: chrome.extension.getURL('/somepage.htm'),
active: true
}, function(_tab) {
chrome.tabs.sendMessage(_tab.id, {
message: 'some custom message',
arg: 'some arg'
});
});
在此调用之后,其中一个脚本(包含在打开的页面的标题中)必须接收此消息并执行进一步操作:
(function(window, document, jQuery) {
"use strict";
chrome.runtime.onMessage.addListener(function(message) {
// Do stuff
});
})(window, document, jQuery);
现在我的问题:
如果 tabAction 设置为"创建",一切正常 - 正在加载页面,主脚本发送消息,扩展调试器显示:"调用的选项卡.sendMessage"和"Notification of runtime.onMessage",页面脚本执行它必须执行的操作。
如果 tabAction 设置为"update" - 页面被正确重定向,主脚本也发送消息,但消息没有发送到运行时;调试器只是在"调用的tabs.sendMessage"处停止。
为什么会有这种奇怪的行为?感谢您的所有进一步回复。
不能保证在调用chrome.tabs.create
或chrome.tabs.update
的回调时页面已完全加载。
如果在调用 chrome.tabs.sendMessage
时页面未完成加载,则页面不会收到该消息(您可能会看到"无法建立连接。接收端不存在",如果选中chrome.runtime.lastError.message
)。
解决问题的正确方法是使用 chrome.tabs.onUpdated
来检测选项卡何时完成加载:
chrome.tabs.update({
url: chrome.runtime.getURL('/somepage.htm')
}, 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(tabId, 'custom message whatever');
}
});
});
由于 crbug.com/411225,这目前不适用于chrome.tabs.create
。在修复该错误之前,您必须使用以下方法:
var tabAction = 'create'; // Or update.
chrome.tabs[tabAction]({
url: chrome.runtime.getURL('/somepage.htm')
}, function(tab) {
// Called when the tab is ready.
var onready = function() {
onready = function() {}; // Run once.
chrome.tabs.onUpdated.removeListener(listener);
// Now the tab is ready!
chrome.tabs.sendMessage(tab.id, 'custom message whatever');
};
// Detect update
chrome.tabs.onUpdated.addListener(listener);
// Detect create (until crbug.com/411225 is fixed).
chrome.tabs.get(tab.id, function(tab) {
if (tab.status === 'complete') {
onready();
}
});
function listener(tabId, changeInfo) {
if (tabId === tab.id && changeInfo.status == 'complete') {
onready();
}
}
});
我在chrome扩展程序中遇到了类似的chrome.tabs.sendMessage问题,我在manifest.json中使用以下代码片段解决了它。请注意,这里最重要的事情是"匹配":内容脚本清单中的["http:///"],因为使用和不使用它测试代码分别会产生成功和错误场景。
"background": {
"scripts": [ "background.js" ],
"persistent": false
},
"content_scripts": [ {
"js": [ "content.js" ],
"all_frames": true,
"matches": [ "http://*/*"]
}],