【发布时间】:2011-09-06 08:57:48
【问题描述】:
是否可以从内容脚本访问该选项卡的 ID?我想从内容脚本向后台页面发送一条消息,告诉我的扩展使用 chrome.tabs.* api“使用此选项卡执行某些操作”。需要一个 TabID,当我的内容脚本可以简单地告诉它消息内容中的 TabID 时,在后台页面中执行一堆逻辑来寻找 TabID 是没有意义的。
【问题讨论】:
是否可以从内容脚本访问该选项卡的 ID?我想从内容脚本向后台页面发送一条消息,告诉我的扩展使用 chrome.tabs.* api“使用此选项卡执行某些操作”。需要一个 TabID,当我的内容脚本可以简单地告诉它消息内容中的 TabID 时,在后台页面中执行一堆逻辑来寻找 TabID 是没有意义的。
【问题讨论】:
Tab id 在MessageSender 对象中自动传递:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
console.log("sent from tab.id=", sender.tab.id);
});
【讨论】:
如果您使用 Ports 进行双向长寿命连接,则回调中的第二个参数是 Port 对象,因此访问选项卡 ID 是:
chrome.runtime.onConnect.addListener(port => {
if (port.name === "foo") {
port.onMessage.addListener((msg, sendingPort) => {
console.log("sent from tab.id=", sendingPort.sender.tab.id);
});
}
});
【讨论】:
如果您想要自己的tabId(在我的情况下是内容脚本)而不需要“tabs”权限,解决方法是让内容脚本向后台脚本发送虚拟消息,然后让后台脚本响应sender.tab.id 回到内容脚本!
例如在content.js:
chrome.runtime.sendMessage({ text: "what is my tab_id?" }, tabId => {
console.log('My tabId is', tabId);
});
在background.js:
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.text == "what is my tab_id?") {
sendResponse({tab: sender.tab.id});
}
});
这是一个对我有用的愚蠢的解决方法。 :)
PS。哦,如果你有tabs 权限,那么你可以很容易地运行这个异步查询:
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
var myTabId = tabs[0].id;
chrome.tabs.sendMessage(myTabId, {text: "hi"}, function(response) {
alert(response);
});
});
【讨论】:
现在选择的答案更正:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
console.log("sent from tab.id=", sender.id);
});
【讨论】:
如果以编程方式注入内容脚本,
另一种方法是将tabId 存储在全局变量中:
const injectTabId = (callback) => chrome.tabs.executeScript(
tabId,
{code: `window.tabId = ${tabId}`},
callback
);
const injectFile = () => chrome.tabs.executeScript(
tabId,
{file: 'content.js'}
);
injectTabId(injectFile);
在内容脚本中,使用window.tabId 访问它。变量
不会因为内容脚本而暴露于页面脚本
生活在一个孤立的世界中。
【讨论】: