Расширение Chrome/FF/Safari: загрузка скрытой веб-страницы в режиме инкогнито
Можно ли создать "режим инкогнито" для загрузки фоновых веб-страниц в расширении браузера?
Я пишу кросс-браузерное расширение не IE, которое периодически проверяет веб-страницы от имени пользователя. Есть два требования:
- Проверка страниц выполняется в фоновом режиме, чтобы быть как можно более ненавязчивой. Я считаю, что это можно сделать, открыв страницу в новой не сфокусированной вкладке браузера или скрыв ее в изолированном фрейме на фоновой странице расширения.
- Проверки страниц должны работать в "режиме инкогнито", а не использовать / обновлять куки пользователя, историю или локальное хранилище. Это делается для того, чтобы как можно больше остановить проверки, загрязняющие реальное поведение пользователя.
Есть мысли о том, как реализовать этот "режим инкогнито"?
В идеале он будет работать в максимально возможном количестве типов браузеров (не в IE).
Мои текущие идеи:
- Отфильтровывать заголовки файлов cookie из входящих / исходящих http-запросов, связанных с проверками страниц (если я могу определить все из них) (невозможно в Safari?)
- После каждой проверки страницы отфильтруйте страницу из истории пользователя.
Полезные вопросы, которые я нашел:
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);
должен сохранять глобальную ссылку на var на добавленный нами 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
Теперь, чтобы удалить куки с запросов на этой странице, используйте этот код:
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
}