将chrome webrequest的addeventlistener限制为当前选项卡或扩展的主窗口

时间:2014-12-18 07:40:49

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

我正在尝试修复现有Chrome扩展程序中的一些问题。该扩展应该改变作为其一部分的子帧的用户代理。现在的问题是,当事件发生并且我更改了标题的用户代理时,它会反映在浏览器中的所有选项卡上,并强制其他选项卡中的其他安全登录注销。我想更改扩展名的特定选项卡的用户代理。这是我在background.js中使用的代码



var requestFilter = {
    urls: [
        "<all_urls>"
    ],
    types: ["main_frame", "sub_frame"]
};

chrome.tabs.query({
        'active': true,
        'windowId': chrome.windows.WINDOW_ID_CURRENT
    },
             
    function(tabs) {
        chrome.webRequest.onBeforeSendHeaders.addListener(function(details) {
            var headers = [];
            headers = details.requestHeaders;
            if (!localStorage['user-agent']) {


                return;
            }
            for (var i = 0; i < headers.length; i++) {
                if (headers[i].name != 'User-Agent') {
                    headers[i].name = 'User-Agent';
                    headers[i].value =

                        localStorage['user-agent'];
                }
            }
            return {
                requestHeaders: headers
            };
        }, requestFilter, ['requestHeaders', 'blocking']);
    });

function focusOrCreateTab(url) {
    chrome.windows.getAll({
        "populate": false
    }, function(windows) {
        var existing_tab = null;
        for (var i in windows) {
            var tabs = windows[i].tabs;
            for (var j in tabs) {
                var tab = tabs[j];
                if (tab.url == url) {


                    existing_tab = tab;
                    break;
                }
            }
        }
        if (existing_tab) {
            chrome.tabs.update(existing_tab.id, {
                "selected": true
            });
        } else {
            chrome.tabs.create({
                "url": url,
                "selected": true
            });
        }
    });
}

chrome.browserAction.onClicked.addListener(function(tab) {
    var manager_url = chrome.extension.getURL("youTube_tool.html");
    focusOrCreateTab(manager_url);
});
&#13;
&#13;
&#13;

请帮助我。我被困了两个星期: - (

2 个答案:

答案 0 :(得分:3)

只要加载后台脚本,就会直接进行chrome.tabs.query({active:true, ...})调用(因此一次)。这是不正确的,您的回调只会在加载扩展程序时收到活动标签。

要解决此问题,请在需要活动标签时致电chrome.tabs.query 对于您的特定情况,根本不需要:chrome.browserAction.onClicked事件在单击时会收到当前选项卡的Tab对象。在对象中,您可以使用tab.id获取标签的ID,并将此值分配给requestFilter.tabId,如下所示,将事件监听器限制为该特定标签:

chrome.browserAction.onClicked.addListener(function(tab) {
    chrome.webRequest.onBeforeSendHeaders.addListener(function(details) {
        // do whatever you want.
    }, {
        urls: [
            '*://*/*'
        ],
        types: ['main_frame', 'sub_frame'],
        tabId: tab.id
    }, ['requestHeaders', 'blocking']);
});

注意:如果您希望能够删除事件,则必须将回调保存在某个全局变量中。下面的示例显示了如何切换阻止当前选项卡中所有文档请求的事件侦听器。

var listeners = {};
chrome.browserAction.onClicked.addListener(function(tab) {
    if (listeners[tab.id]) {
        // Callback was previously set. Remove the listeners.
        chrome.webRequest.onBeforeRequest.removeListener(listeners[tab.id]);
        delete listeners[tab.id];
        chrome.browserAction.setBadgeText({
            text: '',
            tabId: tab.id
        });
    } else {
        listeners[tab.id] = function(details) {
            return {cancel: true};
        };
        chrome.webRequest.onBeforeRequest.addListener(listeners[tab.id], {
            urls: ['*://*/*'],
            types: ['main_frame', 'sub_frame'],
            tabId: tab.id
        }, ['blocking']);
        // Show indicator to show that the extension is active.
        chrome.browserAction.setBadgeText({
            text: 'ON',
            tabId: tab.id
        });
    }
});

// Remove obsolete listener when the tab is closed.
chrome.tabs.onRemoved.addListener(function(tabId) {
    if (listeners[tabId]) {
        chrome.webRequest.onBeforeRequest.removeListener(listeners[tabId]);
        delete listeners[tabId];
    }
});

这是一个最小的manifest.json来测试前面的代码(background.js):

{
    "name": "Toggle requests for a specific tab",
    "version": "1",
    "manifest_version": 2,
    "background": {
        "scripts": ["background.js"],
        "persistent": true
    },
    "browser_action": {
    },
    "permissions": [
        "webRequest",
        "webRequestBlocking",
        "*://*/*"
    ]
}

答案 1 :(得分:0)

the docs中显而易见且明确:RequestFilter可以包含标签ID。

chrome.tabs.query({
    'active': true,
    'currentWindow': true // A much better way to write this
  },       
  function(tabs) {
    requestFilter.tabId = tabs[0].id; // Set the tab to filter on
    chrome.webRequest.onBeforeSendHeaders.addListener(function(details) {
      /* ... */