Расширение Chrome / FF / Safari: загрузка скрытой веб-страницы в режиме инкогнито.

Можно ли создать «режим инкогнито» для загрузки фоновых веб-страниц в расширении браузера?

Я пишу кроссбраузерное расширение, отличное от IE, которое периодически проверяет веб-страницы от имени пользователя. Есть два требования:

  1. Проверка страниц выполняется в фоновом режиме, чтобы быть максимально ненавязчивой. Я считаю, что это можно сделать, открыв страницу в новой несфокусированной вкладке браузера или спрятав в изолированном фрейме iframe на фоновой странице расширения.
  2. Проверки страниц должны работать в «режиме инкогнито», а не использовать / обновлять файлы cookie пользователя, историю или локальное хранилище. Это сделано для того, чтобы проверки не влияли на фактическое поведение пользователя при просмотре страниц в максимально возможной степени.

Есть идеи, как реализовать этот "режим инкогнито"?

В идеале он работал бы с максимально возможным количеством типов браузеров (но не с IE).

Мои текущие идеи:

  • Отфильтровать заголовки файлов cookie из входящих / исходящих HTTP-запросов, связанных с проверками страницы (если я могу идентифицировать все это) (невозможно в Safari?)
  • После каждой проверки страницы отфильтровывайте страницу из истории пользователя.

Я нашел полезные SO-вопросы:


person huczilla    schedule 15.03.2014    source источник


Ответы (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, которую мы добавили. то вы можете изменить местоположение 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

}

person Noitidart    schedule 15.03.2014
comment
чтобы сделать обратное удалению из истории, вы можете добавить в историю вот так: var historyService2 = Components.classes["@mozilla.org/browser/nav-history-service;1"].getService(Components.interfaces.nsIGlobalHistory2); historyService2.addURI(Services.io.newURI('http://www.bing.com/'), false, true, null); - person Noitidart; 16.03.2014
comment
Какой при подробном отзыве! Три вещи: 1) Не могли бы вы исправить форматирование кода? Вроде не хватает местами. 2) Файлы cookie также необходимо удалить из ответов http. Я полагаю, мы могли бы создать httpResponseObserver, который слушал бы «http-on-explore-response»? 3) Используется ли для чего-нибудь переменная myTabToSpoofIn? - person huczilla; 16.03.2014
comment
ах нет, я оставил myTabToSpoofIn случайно, это из другого примера, который я опубликовал. вам просто нужно сохранить глобальную ссылку на iframe. да, происходит удаление файлов cookie, см. фиксированное форматирование, оно там, httpChannel.setRequestHeader('Cookie', '', false); - person Noitidart; 17.03.2014
comment
Спасибо! Ответ принят. Я все еще работаю над расширением Firefox, но ваша информация выглядит действительно полезной. В настоящее время работаю над версией Chrome. - person huczilla; 20.03.2014