获取当前选项卡 ID 的最简单方法?

Simplest Way to get the current Tab Id?

我真的不明白 Chrome 扩展 API 是如何工作的。很难理解 background.js 和 content.js 是如何工作的,但我目前的问题是,函数 insertCSS();似乎需要 tabId,即使官方文档说它是可选的。

所以,这个平台上的 none 个答案可以帮助我,因为我什至不了解整个 API 的概念。

谁能解释一下,为什么这样的事情不可能?

var tabInfo = chrome.tabs.getCurrentTab();

var id = tabInfo.tabId;

这里有几个问题需要回答。

文字问题

So can anybody explain me, why something like this is not possible?

var tabInfo = chrome.tabs.getCurrentTab();

简答:因为大多数 Chrome API 没有 return 值;它是 异步的 ,这意味着 Chrome 的某些其他组件将在 JS 执行恢复时获取答案。

可以在 this canonical question.

阅读 JS 异步性的综合概述

有两种处理方法:

  • 使用回调,并注意实际的回调执行发生在其余调用代码之后。
  • 使用 async/await and/or 承诺。 WebExtension polyfill 可以帮助解决这个问题,但这超出了问题的范围。

标题中的问题

Simplest Way to get the current Tab Id?

或"why chrome.tabs.getCurrentTab won't help you".

chrome.tabs.getCurrentTab() return 是 调用页面的选项卡 ID。 请参阅 docs

这是有限的用途:只有扩展页面(而不是内容脚本)可以调用它 API。

扩展页面是:

  • 背景(无标签 ID),
  • 弹出窗口(无标签 ID),
  • 选项页面(它很复杂,因为它嵌入在 Chrome 页面中),
  • "other" 在可见选项卡中打开的扩展页面(此处,它按预期工作)。

这不是您在评论中确定的用例。

获取当前活动选项卡的实际方法是 chrome.tabs.query() 使用查询 {active: true, currentWindow: true},但请继续阅读。

您遇到的实际问题

根据评论重建,这是您遇到的实际情况:

I have an event in a content script. I need to call the tabs.insertCSS API, so I'm messaging the background page to do it for me. How do I get the tabId for this call?

嗯,这里的关键是仔细看看runtime.onMessage event listener签名:

The callback parameter should be a function that looks like this:

function(any message, MessageSender sender, function sendResponse) {...};

什么是 MessageSender

An object containing information about the script context that sent a message or request.

tabs.Tab (optional) tab
The tabs.Tab which opened the connection, if any. This property will only be present when the connection was opened from a tab (including content scripts), and only if the receiver is an extension, not an app.

[...]

Jackpot. 我们正在从内容脚本发送消息,并且听众收到 sender.tab 信息 "for free"。我们只需要快速绕过 tabs API docs 看看 Tab 包含什么,我们已经知道了:

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
  chrome.tabs.insertCSS(sender.tab.id, {/*...*/});
});

误解

my current Problem is, that the function insertCSS() seems to need the tabId, even if the official documentation says that its optional

没有。如果您调用它时省略了 tabId,这使得 details object 成为第一个参数,那么 Chrome 将假定您想要 "the active tab of the current window".

如果您尝试在后台页面的开发工具 window 中执行它,这似乎不起作用。那是因为在这种情况下 没有这样的选项卡。 当前 window 是您要放入控制台命令的选项卡。所以没有 tabId 的调用非常敏感实际是当前 window.

也可能是你没有权限在当前活动标签中注入,那也会失败。

通常,使用特定的选项卡 ID 是值得的,它消除了扩展逻辑的不确定性。