如何在Firefox的一个选项卡中更改用户代理?

时间:2014-03-12 19:20:05

标签: javascript firefox-addon user-agent

我正在开发Firefox扩展程序,我需要更改单个选项卡的用户代理。我使用过用户代理切换器等扩展,但它只允许我在整个浏览器中更改用户代理。你知道这是否可能吗?我在哪里可以阅读?

非常感谢, -G。

1 个答案:

答案 0 :(得分:3)

这是一个有趣的插件。我想制作一个只在单个标签中启用代理的插件,我想这会帮助你让我很快就能做到这一点

复制粘贴代码。它将在选项卡1中加载的所有内容中欺骗用户代理。在所有其他选项卡中,它将让负载通过。但是如果没有loadContext,你将无法分辨它来自哪个标签,所以可能只是忽略它并放手。

我们需要来自ppl的建议更有经验然后我。在什么情况下我们得到一个null loadContext?

到复制粘贴代码

const {classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu, results: Cr, manager: Cm} = Components;
Cu.import('resource://gre/modules/Services.jsm');

var myTabToSpoofIn = Services.wm.getMostRecentBrowser('navigator:browser').gBrowser.tabContainer[0]; //will spoof in the first tab of your browser

var httpRequestObserver = {
    observe: function (subject, topic, data) {
        var httpChannel, requestURL;

        if (topic == "http-on-modify-request") {
            httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
            var goodies = loadContextGoodies(httpChannel)
            if (goodies) {
              if (goodies.aTab == myTabToSpoofIn) {
                httpChannel.setRequestHeader('User-Agent', 'user agent spoofeddddd', false);
              } else {
                //we arent spoofing in this tab so ignore it
              }
            } else {
                //no goodies so we dont know what tab its from, im not sure when we dont have a loadContext we need to ask other ppl
                //no goodies for this channel, so dont know what tab its in so probably just load this, your decision though, make it option to user, if cannot find associated load context ask user if they want the data to be loaded with default user agent or just not load it at all
                //httpChannel.cancel(Cr.NS_BINDING_ABORTED); //uncomment this to abort it
            }
        }
    }
};

Services.obs.addObserver(httpRequestObserver, "http-on-modify-request", false);
//Services.obs.removeObserver(httpRequestObserver, "http-on-modify-request", false); //run this on shudown of your addon otherwise the observer stags registerd







//this function gets the contentWindow and other good stuff from loadContext of httpChannel
function loadContextGoodies(httpChannel) {
    //httpChannel must be the subject of http-on-modify-request QI'ed to nsiHTTPChannel as is done on line 8 "httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);"
    //start loadContext stuff
    var loadContext;
    try {
        var interfaceRequestor = httpChannel.notificationCallbacks.QueryInterface(Ci.nsIInterfaceRequestor);
        //var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow); //not to be done anymore because: https://developer.mozilla.org/en-US/docs/Updating_extensions_for_Firefox_3.5#Getting_a_load_context_from_a_request //instead do the loadContext stuff below
        try {
            loadContext = interfaceRequestor.getInterface(Ci.nsILoadContext);
        } catch (ex) {
            try {
                loadContext = subject.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext);
            } catch (ex2) {}
        }
    } catch (ex0) {}

    if (!loadContext) {
        //no load context so dont do anything although you can run this, which is your old code
        //this probably means that its loading an ajax call or like a google ad thing
        return null;
    } else {
        var contentWindow = loadContext.associatedWindow;
        if (!contentWindow) {
            //this channel does not have a window, its probably loading a resource
            //this probably means that its loading an ajax call or like a google ad thing
            return null;
        } else {
            var aDOMWindow = contentWindow.top.QueryInterface(Ci.nsIInterfaceRequestor)
                .getInterface(Ci.nsIWebNavigation)
                .QueryInterface(Ci.nsIDocShellTreeItem)
                .rootTreeItem
                .QueryInterface(Ci.nsIInterfaceRequestor)
                .getInterface(Ci.nsIDOMWindow);
            var gBrowser = aDOMWindow.gBrowser;
            var aTab = gBrowser._getTabForContentWindow(contentWindow.top); //this is the clickable tab xul element, the one found in the tab strip of the firefox window, aTab.linkedBrowser is same as browser var above //can stylize tab like aTab.style.backgroundColor = 'blue'; //can stylize the tab like aTab.style.fontColor = 'red';
            var browser = aTab.linkedBrowser; //this is the browser within the tab //this is where the example in the previous section ends
            return {
                aDOMWindow: aDOMWindow,
                gBrowser: gBrowser,
                aTab: aTab,
                browser: browser,
                contentWindow: contentWindow
            };
        }
    }
    //end loadContext stuff
}

也是一张纸条。因为您想要更改用户请求,请确保在httpChannel.setRequestHeader('MyCustomRequestHeader', 'hiiii', false);中将第三个参数设置为false,否则它会将预先存在的用户代理与您提供的新用户代理合并