为什么在 Chrome 扩展程序中使用 RequireJS 调用 chrome.tabs.query() 时不返回选项卡的 URL?

问题描述 投票:0回答:5

我有一个简单的 Chrome 扩展,可以添加浏览器操作。 当扩展程序的弹出窗口打开时,它需要访问当前选项卡的 URL。 由于它不需要访问所有选项卡,因此我只拥有清单中指定的

activeTab
权限:

{
    "manifest_version": 2,
    "name": "RequireJS Test",
    "version": "0.0.1",
    "description": "Test RequireJS and the activeTab permission.",
    "permissions": [
        "activeTab"
    ],
    "browser_action": {
        "default_popup": "popup.html"
    },
    "web_accessible_resources": [
        "js/*",
        "html/*",
        "css/*",
        "img/*"
    ]
}

理论上,这应该让弹出窗口能够访问活动选项卡的 URL,但是当我在弹出窗口的

require()
文件中的
main.js
调用中查询选项卡时,不会返回 URL:

require([], function() {
    chrome.tabs.query({"active": true, "lastFocusedWindow": true}, function (tabs) {
        var url = tabs[0].url;
        console.log("URL from main.js", url);
    });

    console.log("URL from global var accessed in main.js", tabURL);
});

控制台显示 URL 的

undefined
。 但是,如果我从不使用
require()
的普通 .js 文件进行相同的调用,它就可以正常工作:

chrome.tabs.query({"active": true, "lastFocusedWindow": true}, function (tabs) {
    tabURL = tabs[0].url;
    console.log("URL from get-url.js", tabURL);
});

这会显示正确的 URL,我可以在

tabURL
调用中访问全局
require()
就好了。 当我右键单击浏览器按钮并检查弹出窗口时,控制台输出如下所示:

URL from get-url.js http://stackoverflow.com/questions/ask
URL from global var accessed in main.js http://stackoverflow.com/questions/ask
URL from main.js undefined

更奇怪的是,我有时

chrome.tabs.query()
调用中看到了对
require()
的调用中可用的URL。 但大多数情况下它不起作用。 有关 RequireJS 如何加载脚本的问题似乎让 Chrome 感到困惑,并剥夺了加载脚本的 URL 访问权限。 这是 Windows 上的 Chrome 40 中的情况。

显然,解决方法是在单独的脚本中获取 URL 并将其存储在变量中,但这感觉有点笨拙。 我想看看是否有合适的方法让它与 RequireJS 一起工作。

如果有人想在自己的机器上测试它,完整的插件源在这里:https://github.com/fwextensions/requirejs-url-test


编辑

正如 Rob W. 下面所解释的,这实际上与 RequireJS 无关。 上面的

get-url.js
文件中的代码返回正确 URL 的唯一原因是它恰好在 devtools 窗口打开之前运行。 如果我将该文件更改为:

setTimeout(function() {
chrome.tabs.query({"active": true, "lastFocusedWindow": true}, function (tabs) {
    tabURL = tabs[0].url;
    console.log("URL from get-url.js", tabURL);
});
}, 5000);

然后它在 devtools 窗口打开后运行,但也失败。 RequireJS 不是罪魁祸首。

javascript google-chrome google-chrome-extension requirejs
5个回答
60
投票

您看不到 URL,因为您只设置了

activeTab
权限(而不是
tabs
)权限,并且最后一个聚焦窗口是开发人员工具(您没有
activeTab
访问权限)(从 Chrome 41 开始,开发工具选项卡/窗口 对扩展程序不可见,因此
tabs
将是一个空数组)。

好消息是,此问题特定于为扩展页面打开的 devtools 窗口,因此该问题仅出现在开发过程中,而不是用户实际使用过程中。

扩展弹出窗口与窗口关联,因此您可以使用

chrome.tabs.query
currentWindow:true
来获得正确答案:

chrome.tabs.query({
    active: true,
    currentWindow: true
}, function(tabs) {
    var tabURL = tabs[0].url;
    console.log(tabURL);
});

11
投票

为了克服 Rob W. 在他的帖子中报告的 devTools 错误,以下

getActiveTab
解决方法似乎始终对我有用(即使打开了多个 devTools 窗口)。 它的工作原理是,每当
activeTabId
事件触发时,始终在后台页面中保存对
tabs.onActivated
的引用。

var activeTabId;

chrome.tabs.onActivated.addListener(function(activeInfo) {
  activeTabId = activeInfo.tabId;
});

function getActiveTab(callback) {
  chrome.tabs.query({ currentWindow: true, active: true }, function (tabs) {
    var tab = tabs[0];

    if (tab) {
      callback(tab);
    } else {
      chrome.tabs.get(activeTabId, function (tab) {
        if (tab) {
          callback(tab);
        } else {
          console.log('No active tab identified.');
        }
      });

    }
  });
}

2
投票

错误,解决方法是(在“service_worker”:“background.js”中):

var activeTab; // Workaround for bug https://bugs.chromium.org/p/chromium/issues/detail?id=462939

// On activated tabs (triggered immediately after declaration)
chrome.tabs.onActivated.addListener(function(tab) {
    activeTab = tab;
    console.debug(activeTab);
});

0
投票

我也有同样的问题。 通过添加您要访问的主机的权限来修复它。

"host_permissions": [
  "https://www.blogger.com/",
  "https://*.google.com/"
],

https://developer.chrome.com/extensions/declare_permissions


0
投票

通过编辑“manifest.json”文件解决: “权限”:[ “标签”, “活动选项卡”, “贮存” ]

© www.soinside.com 2019 - 2024. All rights reserved.