Obtaining "this" tab ID from content script in Chrome extension?
From a content script, is it possible to access that tab's ID? I want to send a message to the background page from the content script that tells my extension to "do something with this tab" using the chrome.tabs.* api. A TabID is needed, and there is no point in doing a bunch of logic in the background page to hunt for a TabID when my content script can simply tell it the TabID in the message contents.
Tab id is automatically passed inside MessageSender object:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
console.log("sent from tab.id=", sender.tab.id);
});
If you want the tabId
of yourself (in my case in Content Script) without requiring "tabs
" permission, a workaround is to have Content Script send a dummy message to the background script, then have background script respond with sender.tab.id
back to the Content Script!
e.g. in content.js
:
chrome.runtime.sendMessage({ text: "what is my tab_id?" }, tabId => {
console.log('My tabId is', tabId);
});
and in background.js
:
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.text == "what is my tab_id?") {
sendResponse({tab: sender.tab.id});
}
});
it's a stupid workaround that worked for me. :)
PS. Oh, if you have tabs
permission then you can run this async query very easily:
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
var myTabId = tabs[0].id;
chrome.tabs.sendMessage(myTabId, {text: "hi"}, function(response) {
alert(response);
});
});
If you're using Ports for two-way long-lived connections, the second argument in the callback is a Port object, so to access the tab ID is then:
chrome.runtime.onConnect.addListener(port => {
if (port.name === "foo") {
port.onMessage.addListener((msg, sendingPort) => {
console.log("sent from tab.id=", sendingPort.sender.tab.id);
});
}
});
If a content script is injected programmatically,
another approach is to store tabId
in a global variable:
const injectTabId = (callback) => chrome.tabs.executeScript(
tabId,
{code: `window.tabId = ${tabId}`},
callback
);
const injectFile = () => chrome.tabs.executeScript(
tabId,
{file: 'content.js'}
);
injectTabId(injectFile);
In the content script, access it with window.tabId
. The variable
won't be exposed to page scripts because of content scripts
living in an isolated world.