2014-02-21 45 views
3

我正在使用SDK創建Firefox插件。我的目標很簡單,攔截特定的iframe並加載我自己的HTML頁面(與我的插件一起打包爲資源),而不是最初請求的內容。嘗試從Firefox插件中的資源加載內容時出現安全錯誤(SDK)

到目前爲止,我有以下代碼:

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裝載和不正確的重定向。但是,我收到以下錯誤:

Security Error: Content at http://url.com may not load or link to jar:file:///.../pages/test.html.

我該如何解決此限制?

回答

3

其實男人我真的在想這個。

當我更改爲使用loadContext時,它已經解決了。現在,當你得到loadContext你什麼瀏覽器元素(標籤瀏覽器,或框架或iframe)的contentWindow,然後就放棄了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');

+0

我也採用了這種方法。問題是,在我的情況下,我試圖捕獲一個iframe(與此代碼一起工作)的導航,然後重定向iframe(而不是頂部窗口)。提供的代碼嘗試導航頂部窗口而不是iframe。我試過這種方法:loadContext.associatedWindow.frameElement.src ='chrome://kaboom-data/content/test.html';即使使用chrome.manifest也會產生相同的安全錯誤 –

+0

你確定是男士嗎?毫無疑問,loadContext.associatedWindow是加載的contentWindow,所以它的iframe或框架或頂部窗口。我沒有在這個範圍內測試過,但之前。你能告訴我如何重現你的情況嗎?生病測試 – Noitidart

+1

幾個星期前我在loadContext上完成的非常繁重的測試以及它如何獲得它實際加載的地方的窗口可以在這裏找到(https:// github .com/Noitidart/loadcontext-and-http-modify-observer)和[here](https://github.com/Noitidart/demo-nsITraceableChannel)。現在,如果你真的不想這樣做,那麼你可以求助於添加事件監聽器,如[這裏](https://gist.github.com/Noitidart/8685542)或者你可以使用Web進程監聽器,你也可以使用documjent見元素插入的觀察者[here](https://gist.github.com/Noitidart/8704127)。 loadContext最容易 – Noitidart

1

看到這個插件在這裏:https://addons.mozilla.org/en-US/firefox/addon/ghforkable/?src=search

在chrome.manifest用於文件

我們設置contentaccessible參數設置爲yes

你不需要SDK的這個插件。它如此簡單,只需ocpy粘貼到一個引導骨架在這裏看到:

Bootstrap With Some Features, Like chrome.manifest which you will need

Bootstrap Ultra Basic

如果你想真正做一個頁面的重定向到您的網站,也許你想自定義關於頁面?如果您想爲您製作關於頁面的自定義問題,請收集演示文稿。你可以看到一個有點難以理解演示here

+0

不幸的是,這並沒有幫助我克服駝峯。我已經在插件中實現了其他功能,所以我很難回過頭來重新開始,而不使用SDK。 - 似乎設置內容策略將有助於將互聯網iframe重定向到本地資源。 –

+0

將你的插件上傳到github上(我更喜歡github,但別的東西也可以),不適合你。 – Noitidart

+1

已上傳。我邀請你參加我的私人回購。 –

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); 
httpChannel.redirectTo(myuri); 

Error Thrown

Security Error: Content at http://digg.com/tools/diggthis/confirm ? may not load or link to 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]

alias updated to 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); 

錯誤時,拋出

Security Error: Content at http://digg.com/tools/diggthis/confirm ? may not load or link to 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方法,它的工作真的困擾着我。我所做的更改是我的本地副本。

+0

實際上,如果您在html中創建一個iframe並將其設置爲鉻路徑,即使內容可訪問它不會加載。它與安全[這裏](https://developer.mozilla.org/en-US/docs/Displaying_web_content_in_an_extension_without_security_issues)有一個白名單tho的方式也許@WladimirPalant可以幫助這裏,他寫道,文章 – Noitidart

+0

也跟着這個主題,我問了一些幫助,並發現了一個類似的問題,當我們將iframe的src設置爲chrome位置時。 [url to topic](http://forums.mozillazine.org/viewtopic.php?f=19&t=2805023) – Noitidart

+0

好男人我不能這樣做,我試了很多。讓我給你我的代碼,因爲它是一個私人回購,我應該如何給你的代碼?代碼顯示瞭如何使用loadContext和Services.jsm – Noitidart

1

您是否考慮將您的本地HTML文件轉換爲數據網址並加載?

+0

是的。這個問題是我無法引用關聯的JS/CSS文件。我將不得不將所有內容嵌入到一個單獨的html文件中。 –

相關問題