Вопрос по firefox-addon, firefox-addon-sdk – Ошибка безопасности при попытке загрузить контент из ресурса в Firefox Addon (SDK)

3

Я создаю аддон Firefox с помощью SDK. Моя цель проста: перехватить определенный iframe и загрузить собственную HTML-страницу (упакованную как ресурс с моим аддоном) вместо содержимого, которое было запрошено изначально.

Пока у меня есть следующий код:

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

        if (topic == "http-on-modify-request") {
            httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
            requestURL = httpChannel.URI.spec;

            var newRequestURL, i;

            if (/someurl/.test(requestURL)) {
                var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);

                httpChannel.redirectTo(ioService.newURI(self.data.url('pages/test.html'), undefined, undefined));
            }

            return;
        }
    }
};

var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
observerService.addObserver(httpRequestObserver, "http-on-modify-request", false);

Этот код работает в том смысле, что он определяет правильную загрузку iframe и правильно выполняет перенаправление. Однако я получаю следующую ошибку:

Ошибка безопасности: содержимое вhttp://url.com может не загружаться или ссылаться на jar: file: ///.../pages/test.html.

Как я могу обойти это ограничение?

Ваш Ответ

4   ответа
3

на самом деле человек, я был действительно над этим думать.

это уже решено, когда я перешел на использование loadContext. Теперь, когда вы получаете loadContext, вы получаете contentWindow любого элемента браузера (браузера с вкладками, или фрейма или iframe), а затем просто прерываете запрос http, как вы делаете, и затемloadContext.associatedWindow.document.location = self.data('pages/tests.html');

сделанный

Я вставлю сюда код, удалив все личные вещи. вам может понадобиться chrome.manifest, протестируйте его и вставьте сюда код

Cu.import('resource://gre/modules/Services.jsm');

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

        if (topic == "http-on-modify-request") {
            httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
            requestURL = httpChannel.URI.spec;

            var newRequestURL, i;

            if (/someurl/.test(requestURL)) {
                var goodies = loadContextGoodies(httpChannel);
                if (goodies) {
                    httpChannel.cancel(Cr.NS_BINDING_ABORTED);
                    goodies.contentWindow.location = self.data.url('pages/test.html');
                } else {
                    //dont do anything as there is no contentWindow associated with the httpChannel, liekly a google ad is loading or some ajax call or something, so this is not an error
                }
            }

            return;
        }
    }
};
Services.obs.addObserver(httpRequestObserver, "http-on-modify-request", false);





//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
}

НОТА: Теперь попробуйте сначала, я еще не тестировал, если вы получаете ошибку безопасности при попытке перенаправления, то создайте файл chrome.manifest и поместите его в корневой каталог. Если он выдает ошибку безопасности, то вам определенно нужен файл chrome.manifest, и это, без сомнения, исправит его. Я сам попробую это позже вечером, когда у меня будет время.

Файл chrome.manifest должен выглядеть следующим образом:

content kaboom-data ./resources/kaboom/data/ contentaccessible=yes

Затем приведенным выше кодом измените строку перенаправления сgoodies.contentWindow.location = self.data.url('pages/test.html'); вgoodies.contentWindow.location = 'chrome://kaboom-data/pages/test.html');.

это проще всего, потому что вам не нужно создавать windowListener для добавления слушателя во вновь открытые окна Noitidart
Вы правы. contentWindow.location работал как задумано. Благодарю. im_nullable
Ты уверен, человек? Без сомнения, loadContext.associatedWindow - это загружаемое contentWindow, поэтому это iframe, или фрейм, или верхнее окно. Я проверил это не в этой области, но ранее. Можете ли вы сказать мне, как воспроизвести вашу ситуацию плохо проверить это Noitidart
Я тоже пошел по этому пути. Проблема в том, что в моем случае я пытаюсь захватить навигацию по iframe (которая работает с этим кодом), а затем перенаправить только iframe (не верхнее окно). Предоставленный код пытается перемещаться по верхнему окну вместо iframe. Я попробовал этот подход: loadContext.associatedWindow.frameElement.src = 'chrome: //kaboom-data/content/test.html'; что дает ту же ошибку безопасности даже с chrome.manifest im_nullable
1

размещение моих испытаний здесь, чтобы они могли помочь всем:

трасса 1 ошибка - создан файл chrome.manifest с содержимымcontent kaboom-data resources/kaboom/data/ contentaccessible=yes

var myuri = Services.io.newURI('chrome://kaboom-data/content/pages/test.html', undefined, undefined);
httpCh,annel.redirectTo(myuri);

Ошибка брошена

Ошибка безопасности: содержимое вhttp://digg.com/tools/diggthis/confirm? может не загружаться или ссылаться на jar: file: /// C: /Documents%20and%20Settings/SONY%20VAIO/Application%20Data/Mozilla/Firefox/Profiles/vr10qb8s.default/extensions/[email protected] /resources/kaboom/data/pages/test.html.

испытание 2 не удалось - создан ресурс в bootstrap.js

alias.spec = file: /// C: /Documents%20and%20Settings/SONY%20VAIO/Application%20Data/Mozilla/Firefox/Profiles/vr10qb8s.default/extensions/[email protected]

псевдоним обновлен до spec: jar: file: /// C: /Documents%20and%20Settings/SONY%20VAIO/Application%20Data/Mozilla/Firefox/Profiles/vr10qb8s.default/extensions/[email protected]

   let resource = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
  let alias = Services.io.newFileURI(data.installPath);
  Cu.reportError('alias.spec = ' + alias.spec);
  if (!data.installPath.isDirectory()) {
    alias = Services.io.newURI("jar:" + alias.spec + "!/", null, null);
    Cu.reportError('alias updated to spec: ' + alias.spec);
  }
  resource.setSubstitution("kaboom_data", alias);

...

var myuri = Services.io.newURI('resource://kaboom_data/resources/kaboom/data/pages/test.html', undefined, undefined);
httpChannel.redirectTo(myuri);

Ошибка брошена

Ошибка безопасности: содержимое вhttp://digg.com/tools/diggthis/confirm? может не загружаться или ссылаться на jar: file: /// C: /Documents%20and%20Settings/SONY%20VAIO/Application%20Data/Mozilla/Firefox/Profiles/vr10qb8s.default/extensions/[email protected] /resources/kaboom/data/pages/test.html.

ЗАКЛЮЧЕНИЕ в обоих вышеописанных испытаниях это была самая странная вещь: он не отображал путь ресурса или хрома в выданной ошибке безопасности, но давал полный путь к JAR. Приводит меня к мысли, что это как-то связано с функцией redirectTo.

Решение, которое сработало, было вашим решением

var gBrowser = utils.getMostRecentBrowserWindow().gBrowser;
var domWin = httpChannel.notificationCallbacks.getInterface(Ci.nsIDOMWindow);
var browser = gBrowser.getBrowserForDocument(domWin.document);

//redirect
browser.loadURI(self.data.url('pages/test.html'));

однако я изменил это, чтобы использовать loadContext вместо этого метода, потому что это рекомендуемый способ. также gBrowser для getMostRecentBrowserWindow завершится с ошибкой, если загрузка URL-адреса медленная, и в это время пользователь переключается на другую вкладку или окно

Я также перешел на использование Services.jsm, так как вы все равно импортировали Cu. Использование Services.jsm очень быстро, даже быстро не мигает. Это просто указатель.

Я все еще работаю над попыткой использовать метод redirectTo, который действительно беспокоит меня. Изменения, которые я сделал, относятся к моей локальной копии.

также следуйте этой теме, я попросил о помощи и обнаружил аналогичную проблему, когда мы устанавливаем src из iframe в chrome location.URL к теме Noitidart
хорошо, я не могу это сделать, я много пробовал. позвольте мне дать вам мой код, так как это частный репозиторий, как я должен дать вам код? код показывает, как использовать loadContext и Services.jsm Noitidart
на самом деле, если вы создаете iframe в html и устанавливаете его в путь chrome, даже если он доступен, он не будет загружаться. это связано с безопасностьюВОТ есть способ сделать белый список, но, возможно, @WladimirPalant может помочь здесь, когда он писал эту статью Noitidart
1

Рассматривали ли вы преобразование локального файла HTML в URL-адрес данных и загрузку этого?

Да. Проблема в том, что я не мог ссылаться на связанные файлы JS / CSS. Я должен был бы встроить все в один HTML-файл. im_nullable
1

увидеть этот аддон здесь:https://addons.mozilla.org/en-US/firefox/addon/ghforkable/?src=search

в файле chrome.manifest мы устанавливаем для параметра contentaccessible значение yes

вам не нужен SDK для этого аддона. это так просто, просто вставьте это в скелет начальной загрузки, как показано здесь:

Bootstrap с некоторыми функциями, такими как chrome.manifest, который вам понадобится

Bootstrap Ultra Basic

если вы действительно хотите перенаправить страницу на свой сайт, может быть, вы хотите создать собственную страницу? если вы хотите, чтобы я сделал для вас демо-страницу, создайте кастомную страницу. вы можете увидеть немного трудно понять демоВот

загрузите ваш аддон на github (я предпочитаю github, но что-то еще будет работать), я настрою его для вас. Noitidart
Спасибо, не могли бы вы pacakage это в xpi, чтобы я мог установить, я не знаю, как установить addon-sdk addons, когда нет install.rdf Noitidart
Загружено. Я пригласил вас в мой личный репо. im_nullable
К сожалению, это не помогает мне преодолеть горб. У меня есть другие функции, которые я уже реализовал в аддоне, поэтому мне было бы сложно вернуться и начать все заново, не используя SDK. - Похоже, что настройка политики контента поможет при перенаправлении интернет-фрейма на локальный ресурс. im_nullable
Добавил XPI ... im_nullable

Похожие вопросы