2011-09-28 39 views
3

我想創建一個重寫某些URL的Firefox附加組件。例如,如果頁面嘗試加載文件http://my.com/foo.js,我想重寫URL以便從http://my-other.org/bar.js加載。我不希望它看起來像302重定向,因爲請求可能源於XHR呼叫,並且我不希望瀏覽器以其跨域爲理由拒絕重定向請求。從Firefox附加組件中重寫有選擇性的URL?

我查看了TamperData和HttpFox源代碼,以瞭解如何解決此問題。我試着創建一個觀察器來監聽http-on-modify-request,並在偵聽器中嘗試重寫URL。問題是nsiHttpChannel對象似乎讓我可以做所有事情 - 覆蓋標頭,取消請求,捕獲響應等 - 除了覆蓋URL。簡單地更改nsiHttpChannel的originalURI和URI屬性的內容似乎也不起作用。

我能找到的唯一有希望的指針就是HTTPS無處不在的插件,但代碼相當複雜,而且感覺應該是一種更簡單的方法來實現這一點。

+0

的Greasemonkey和JavaScript的Greasemonkey還支持跨域AJAX調用。 – Anders

+0

@Anders - 或許我不清楚我的問題。我想攔截所有**網絡請求,因爲我需要將所有請求重寫爲相關網址。我的理解是,例如,如果一個頁面加載一個JS文件,然後進行Ajax調用,該調用不能被Greasemonkey捕獲 - 這就是爲什麼我沒有考慮它。我錯了嗎? –

+0

問題http:// stackoverflow。com/questions/3122854 /如何替換一個JavaScript文件請求內容從另一個文件在ff似乎回答同樣的問題... –

回答

1

我們可以這樣做,我重寫了一個新的nsiHttpChannel,這樣做有點複雜,但幸運的是插件https-everywhere實現這個強制一個https連接。

https-everywhere的源代碼可here

最需要這個代碼是在文件

IO Util.js ChannelReplacement.js(在源代碼樹不再)

我們可以一起工作單獨提供的上述文件提供了我們的基本變量,如Cc,Ci設置和定義的功能xpcom_generateQI

var httpRequestObserver = 
{ 
    observe: function(subject, topic, data) { 
    if (topic == "http-on-modify-request") { 

     var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);  
     var requestURL = subject.URI.spec; 

     if(isToBeReplaced(requestURL)) { 

      var newURL = getURL(requestURL);   
      ChannelReplacement.runWhenPending(subject, function() { 
        var cr = new ChannelReplacement(subject, ch); 
        cr.replace(true,null); 
        cr.open(); 
       }); 
     } 
    } 

    }, 

    get observerService() { 
    return Components.classes["@mozilla.org/observer-service;1"] 
        .getService(Components.interfaces.nsIObserverService); 
    }, 

    register: function() { 
    this.observerService.addObserver(this, "http-on-modify-request", false); 

    }, 

    unregister: function() { 
    this.observerService.removeObserver(this, "http-on-modify-request"); 

    } 
}; 


httpRequestObserver.register(); 

該代碼將取代請求不重定向。

雖然我已經很好地測試了上面的代碼,但我不確定它的實現。據我所知,它複製了所請求頻道的所有屬性,並將它們設置爲要覆蓋的頻道。之後以某種方式,原始請求所請求的輸出將使用新通道提供。

P.S.我曾見過一個SO帖子,其中提出了這種方法。

0

gliptak的回答是正確的,但現在已過時。

我寫了一個非常簡單的Firefox插件,完成你所描述的任務。您可以使用其來源作爲參考。

// intercept and occasionally modify HTTP/HTTPS requests... 
let httpObserver = { 
    observe: function (aSubject, aTopic, aData) { 
     aSubject.QueryInterface(Ci.nsIHttpChannel); 
     let url = aSubject.URI.spec; 
     let modUrl = modifyUrlIfNeeded(url); 
     if (modUrl){ 
      // replace URL and referrer in request... 
      let urlObj = ioService.newURI(modUrl, aSubject.URI.originCharset, null); 
      aSubject.redirectTo(urlObj); 
     } 
    } 
}; 
observerService.addObserver(httpObserver, "http-on-modify-request", false); 

https://github.com/tristanisme/gahmm/blob/master/index.js