2009-11-08 127 views
17

如何在Firefox擴展中更改HTTP響應正文?我使用下面的代碼設置了一個http-on-examine-response觀察者和一個nsIStreamListener對象。獲取數據,解析並修改數據後,如何將更改的響應返回給Firefox瀏覽器?例如,假設我在啓用了我的擴展程序的情況下訪問Google.com,擴展程序應攔截響應並將每次發生的「谷歌」更改爲「護目鏡」。所以當頁面加載時,用戶會在任何地方看到「護目鏡」。在Firefox擴展中更改HTTP響應

function TmSteroidsObserver() 
{ 
    this.register(); 
} 


TmSteroidsObserver.prototype = { 
    observe: function(subject, topic, data) { 

    if (topic == "http-on-examine-response") { 

    } 
    else if (topic == "http-on-modify-request") { 
     var channel = subject.QueryInterface(Components.interfaces.nsIChannel); 
     var listener = new StreamListener(channel); 
    } 

    }, 

    register: function() { 
    var observerService = Components.classes["@mozilla.org/observer-service;1"] 
           .getService(Components.interfaces.nsIObserverService); 
    observerService.addObserver(listener, "http-on-modify-request", false); 
    observerService.addObserver(listener, "http-on-examine-response", false); 
    }, 

    unregister: function() { 
    var observerService = Components.classes["@mozilla.org/observer-service;1"] 
          .getService(Components.interfaces.nsIObserverService); 
    observerService.removeObserver(this, "http-on-modify-request"); 
    observerService.removeObserver(this, "http-on-examine-response"); 
    }, 

    QueryInterface : function(aIID) { 
    if (aIID.equals(Components.interfaces.nsISupports) || 
     aIID.equals(Components.interfaces.nsIObserver)) 
     return this; 
    throw Components.results.NS_NOINTERFACE; 
    } 

} 

function StreamListener(channel) { 

    channel.notificationCallbacks = listener; 
    channel.asyncOpen(listener, null); 

} 

StreamListener.prototype = { 
    mData: "", 
    mChannel: null, 

    // nsIStreamListener 
    onStartRequest: function (aRequest, aContext) { 
    this.mData = ""; 
    }, 

    onDataAvailable: function (aRequest, aContext, aStream, aSourceOffset, aLength) { 
    var scriptableInputStream = 
     Components.classes["@mozilla.org/scriptableinputstream;1"] 
     .createInstance(Components.interfaces.nsIScriptableInputStream); 
    scriptableInputStream.init(aStream); 

    this.mData += scriptableInputStream.read(aLength); 
    }, 

    onStopRequest: function (aRequest, aContext, aStatus) { 
    if (Components.isSuccessCode(aStatus)) { 
     // request was successfull 
     this.mCallbackFunc(this.mData); 
    } else { 
     // request failed 
     this.mCallbackFunc(null); 
    } 

    this.mChannel = null; 
    }, 

    // nsIChannelEventSink 
    onChannelRedirect: function (aOldChannel, aNewChannel, aFlags) { 
    // if redirecting, store the new channel 
    this.mChannel = aNewChannel; 
    }, 

    // nsIInterfaceRequestor 
    getInterface: function (aIID) { 
    try { 
     return this.QueryInterface(aIID); 
    } catch (e) { 
     throw Components.results.NS_NOINTERFACE; 
    } 
    }, 

    // nsIProgressEventSink (not implementing will cause annoying exceptions) 
    onProgress : function (aRequest, aContext, aProgress, aProgressMax) { }, 
    onStatus : function (aRequest, aContext, aStatus, aStatusArg) { }, 

    // nsIHttpEventSink (not implementing will cause annoying exceptions) 
    onRedirect : function (aOldChannel, aNewChannel) { }, 

    // we are faking an XPCOM interface, so we need to implement QI 
    QueryInterface : function(aIID) { 
    if (aIID.equals(Components.interfaces.nsISupports) || 
     aIID.equals(Components.interfaces.nsIInterfaceRequestor) || 
     aIID.equals(Components.interfaces.nsIChannelEventSink) || 
     aIID.equals(Components.interfaces.nsIProgressEventSink) || 
     aIID.equals(Components.interfaces.nsIHttpEventSink) || 
     aIID.equals(Components.interfaces.nsIStreamListener)) 
     return this; 

    throw Components.results.NS_NOINTERFACE; 
    } 
}; 

回答

0

觀察員服務只需撥打你的聽衆。 Firefox將收到請求,呼叫您的聽衆併發送回復。請參閱Mozilla文檔Creating HTTP POSTs