我正在为Chrome开发扩展程序,这是我尝试实现的工作流程:
popup发送消息 - >内容脚本1侦听 - >内容脚本1发送消息 - >内容脚本2侦听 - >内容脚本2执行操作
在概念上,这很好,花花公子;我所做的是设置2个监听器:每个内容脚本中有一个:
弹出窗口:
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
console.log('popup send request');
chrome.tabs.sendMessage(tabs[0].id, obj);
});
内容脚本1:
chrome.runtime.onMessage.addListener((function (request, sender) {
this.log('wg got request', 'request', request, 'sender', sender);
if (request.action == 'options-updated') {
this.updateOptions(request, (function() {
var obj = {action: 'refresh', WG: window.WG};
this.log('wg forwarded request');
chrome.runtime.sendMessage(obj); // attempting to forward another request
return true;
}).bind(this));
}
return true;
}).bind(window.WG));
内容脚本2:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
console.log('content script got request', 'request', request, 'sender', sender);
if (request.WG) {
request.WG.log('message', request.action);
if (request.action == 'refresh') {
WGRefresh(request.WG, request.options);
}
}
return true;
});
问题是,内容脚本2只接收第一条消息。所以我得到的输出是:
弹出发送请求 内容脚本得到请求(首先,要忽略) wg得到了请求(同样,首先,不要忽略这里) wg转发请求
然后什么都没有。内容脚本应该再次触发它,并且在请求中我总是发送" action",我在监听器中检查,但是对于我不能区分的日志(它应该始终记录,所以这意味着请求永远不会到达那里。)
我已经尝试在所有听众中返回true,根据文档,它将保持链运行并且在第一次击中后不会停止,但即便如此,它也无法正常工作。我做错了什么?!
答案 0 :(得分:1)
Chrome API中有2个sendMessage
个功能。
chrome.runtime.sendMessage
向所有打开扩展程序页(即背景,弹出窗口等)发送消息chrome.tabs.sendMessage
向所有内容脚本中的发送消息 因此,您第一个内容脚本中对chrome.runtime.sendMessage()
的调用无法访问任何其他内容脚本。
此外,您无法直接从内容脚本中调用chrome.tabs
。
要执行您想要的操作,您需要设置一个后台脚本,它将充当CS1和CS2之间的代理。从技术上讲,你可以使用弹出窗口,但它不可靠,因为弹出窗口可能会被关闭,然后没有人会听。背景页面(或者更好,event page)是专门为此目的而设计的。
因此该方案变为:popup - (tabs.sendMessage
) - > CS1 - (runtime.sendMessage
) - >背景 - (tabs.sendMessage
) - > CS2
请注意,后台页面需要知道要发送邮件的选项卡ID。如果由于某种原因它是相同的标签,例如您尝试跨帧消息,可以在回调中使用sender
参数。
有关详细信息,请参阅Messaging docs。