如何检测它是 chrome 扩展程序开发中的旧标签页还是特殊页面



我想知道当前选项卡是安装扩展之前打开的旧选项卡,还是一个特殊的选项卡(浏览器UI,扩展页面,chrome.google.com),我无法注入内容脚本。

有一个部分的解决方案,我尝试发送消息到内容脚本,如果它抛出一个错误(即内容脚本没有加载在页面上),那么它要么是一个旧的选项卡或一个特殊的页面。我需要一种方法来知道是哪一个这样我就可以通过弹出页面通知你

检测浏览器扩展弹出是否在有内容脚本的选项卡上运行

可能还有一种方法:尝试在页面上执行脚本,如果它成功,那么它是一个旧选项卡,但这需要在清单中再增加一个权限,即scripting,我觉得这有点过分,只是为了检测一个旧选项卡。还有其他可能的解决方案吗?

这是为chrome扩展开发。

如果您只对区分新选项卡与旧选项卡和/或不可注入的选项卡感兴趣,您可以让内容脚本将其选项卡的id添加到会话存储中。稍后,您可以在会话存储中查找任何选项卡的ID。

  • old tab =在安装扩展
  • 之前打开的tab
  • new tab =安装扩展
  • 后打开的tab
  • non-injectable标签=标签,你不能注入内容脚本,看到Chrome扩展postMessage从后台脚本到内容脚本每次在更改标签

选项卡id仅在当前会话期间有效。当您在会话存储中存储选项卡id时,当您启动新会话时,它们就会消失,这正是您想要的。

内容脚本不知道他们正在运行的选项卡的ID,所以他们不能通过直接调用chrome.storage.session.set()来存储它。然而,内容脚本可以向service worker发送消息。service worker会在收到消息的同时收到发送者标签的信息。

下面的概念证明并没有试图确定一个选项卡是否可以注入。

  • 你可以通过检查选项卡的URL来做到这一点,例如,如果它以"chrome://"或"chrome扩展://"。但是我不知道你是否可以确定所有不可注入的标签像这样,例如那些URL被runtime_blocked_hosts策略禁止的。
  • 或者您可以将空内容脚本注入选项卡并检查错误。这需要"脚本"。permission,加上activeTab"或正确的主机权限,但允许您确定所有不可注入的选项卡。

当您单击该操作时,扩展显示通知。它告诉你活动选项卡是旧的,还是新的和/或不可注入的。

manifest.json

{
"manifest_version": 3,
"name": "Tabs with vs without Content Scripts",
"version": "1.0",
"action": {
},
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["*://*/*"],
"js": ["content_script.js"]
}
],
"permissions": [
"notifications",
"storage"
]
}

background.js

async function action_on_clicked(tab) {
let { [tab.id.toString()]: tab_id_stored } = await chrome.storage.session.get(tab.id.toString());
let message;
if (tab_id_stored === undefined) {
/* Old or non-injectable tab */
message = "Old or non-injectable tab";
}
else {
message = "New tab";
}
chrome.notifications.create(
{
iconUrl: "/icon_128.png",
message,
title: "Tabs with vs without Content Scripts",
type: "basic",
},
notificationId => {
if (chrome.runtime.lastError === undefined) {
console.log(notificationId);
}
else {
console.error(chrome.runtime.lastError);
}
}
);
}
function runtime_on_message(message, sender, sendResponse) {
if (message == "store_tab_id") {
if (sender.tab) {
chrome.storage.session.set({ [sender.tab.id.toString()]: true })
.then(() => {
sendResponse("tab id stored");
})
.catch(error => {
sendResponse(error);
});
return true;
}
else {
sendResponse("sender.tab is undefined");
}
}
else {
sendResponse("unknown message");
}
}
chrome.action.onClicked.addListener(action_on_clicked);
chrome.runtime.onMessage.addListener(runtime_on_message);

content_script.js

(async () => {
let response = await chrome.runtime.sendMessage("store_tab_id");
console.log("response", response);
})();

最新更新