0

是否可以构建“隐身模式”以在浏览器扩展中加载背景网页?

我正在编写一个非 IE 跨浏览器扩展,它代表用户定期检查网页。有两个要求:

  1. 页面检查在后台完成,尽可能不引人注目。我相信这可以通过在新的不集中浏览器选项卡中打开页面来完成,或者隐藏在扩展程序背景页面的沙盒 iframe 中。
  2. 页面检查应该在“隐身模式”下运行,而不是使用/更新用户的 cookie、历史记录或本地存储。这是为了尽可能地阻止检查污染用户的实际浏览行为。

关于如何实现这种“隐身模式”的任何想法?

理想情况下,它可以在尽可能多的浏览器类型中工作(不是 IE)。

我目前的想法是:

  • 从与页面检查相关的传入/传出 http 请求中过滤掉 cookie 标头(如果我可以识别所有这些)(在 Safari 中不可能?)
  • 每次页面检查后,从用户的历史记录中过滤掉该页面。

我发现有用的 SO 问题:

4

1 回答 1

1
var Cu = Components.utils;
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/devtools/Console.jsm');
var win = Services.appShell.hiddenDOMWindow
var iframe = win.document.createElementNS('http://www.w3.org/1999/xhtml', 'iframe');
iframe.addEventListener('DOMContentLoaded', function(e) {
    var win = e.originalTarget.defaultView;
    console.log('done loaded', e.document.location);
    if (win.frameElement && win.frameElement != iframe) {
            //its a frame in the in iframe that load
    }
}, false);

win.document.documentElement.appendChild(iframe);

必须保持对我们添加的 iframe 的全局 var 引用。然后您可以像这样更改 iframe 位置,并在加载时触发上面的事件侦听器

iframe.contentWindow.location = 'http://www.bing.com/'

DOMContentLoaded 标识了该 iframe 中加载的所有内容。如果页面有框架,它也会检测到。

要从历史记录中删除,进入 DOMContentLoaded 函数,使用历史记录服务从历史记录中删除 win.location: https ://developer.mozilla.org/en-US/docs/Using_the_Places_history_service

现在要从该页面中的请求中删除 cookie,请使用以下代码:

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.contentWindow.top == iframe.contentWindow.top) {
                httpChannel.setRequestHeader('Cookie', '', false);
              } else {
                //this page load isnt in our iframe so ignore 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

}

于 2014-03-15T20:40:01.307 回答