为什么chrome.tabs.query()在Chrome扩展程序中使用RequireJS调用时会返回标签的URL?

时间:2015-02-28 20:48:21

标签: javascript google-chrome google-chrome-extension requirejs

我有一个简单的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);
});

控制台显示网址undefined。但是,如果我从不使用require()的普通.js文件中进行相同的调用,则可以正常工作:

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

显示正确的网址,我可以在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()来电中可用的网址。但大多数情况下它不起作用。关于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不是罪魁祸首。

2 个答案:

答案 0 :(得分:32)

您没有看到网址,因为您只设置了activeTab权限(而不是tabs)权限,最后一个关注窗口是开发者工具(您为此没有activeTab访问权限(以及自Chrome 41以来,devtools标签/窗口are invisible to extensions,因此tabs将是一个空数组。)

好消息是,此问题特定于为您的扩展程序页面打开的devtools窗口,因此问题仅发生在开发期间,而不是在用户实际使用期间。

扩展程序弹出窗口与窗口相关联,因此您可以chrome.tabs.querycurrentWindow:true一起使用以获得正确答案:

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

答案 1 :(得分:2)

为了克服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.');
        }
      });

    }
  });
}