2010-02-10 10 views
42

मैं अब इस पर लंबे समय से प्रयास कर रहा हूं, और कोई अच्छा नतीजा नहीं है।फ़ायरफ़ॉक्स एक्सटेंशन में रीडायरेक्टिंग अनुरोध (nsiHttpChannel?)

var myObserver = { 
    observe: function(subject, topic, data) 
    { 
     if (topic == "http-on-examine-response") 
     { 
      // implement later 
     } 
     else if(topic == "http-on-modify-request") 
     { 
      // implement later 
     } 
    }, 

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

var obs = new Service("observer-service", "ObserverService"); 
obs.addObserver(myObserver, "http-on-modify-request", false); 

असल में, http-on-modify-request पर, मैं कैसे यूआरआई जांच करने के लिए है, जो खिड़की यह पता लगाने (यदि हो) उससे संबद्ध है, और अन्य सामान का एक गुच्छा पता है। जो मैं समझ नहीं पा रहा हूं कि अनुरोध को पुनर्निर्देशित करना है, जो मुझे पता है, यहां से संभव है, क्योंकि किसी भी अनुरोध को कभी भी भेजे जाने से पहले मुझे nsIHttpChannel मिल सकता है।

कोई भी जानता है कि क्या करना है? :/मैं कुछ हफ्तों के लिए कोशिश कर रहा हूं, और कहीं भी नहीं मिला।

+0

अनुरोध को पुनर्निर्देशित करके आपका क्या मतलब है? ब्राउज़र स्थान को किसी अन्य यूआरएल पर रीडायरेक्ट कर रहा है? –

+3

हां, लेकिन मैं जो कर रहा हूं उसके संदर्भ में। मैंने इसे समझ लिया, अगर मैं इसके चारों ओर घूमता हूं तो मैं दूसरों के लिए समाधान पोस्ट करूंगा। –

+2

वह समाधान संभवतः उपयोगी होगा। –

उत्तर

1

मैं इस धारणा के तहत हूं कि आप इस स्तर पर ऐसा नहीं कर सकते हैं - मैंने कोड को बाहरी रूप से "ट्रिकिंग" करने के विभिन्न तरीकों की कोशिश की जो एनएसआईएचटीपी चैनल बनाने के लिए कहते हैं (उदाहरण के अंत में उदाहरण)।

यदि आप एक रीडायरेक्ट चाहते हैं तो मैं अनुशंसा करता हूं कि चैनल की मालिक विंडो (जो 99% समय काम करता है) से संपर्क करें, और उसे रीडायरेक्ट करने के लिए निर्देश दें। मुझे पता है कि यह वही व्यवहार नहीं करेगा, लेकिन चूंकि मुझे नहीं पता कि आप यह क्यों कर रहे हैं, यह बाहरी रूप से (उपयोगकर्ता के लिए) जैसा ही आप पूछते हैं वही काम कर रहे हैं।

if(aTopic == "http-on-examine-response") {                      
      var request = aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);              

      if(!request.URI.spec.match("^http://www.apple.com/")) {               
       var ios = Components.classes["@mozilla.org/network/io-service;1"]                
        .getService(Components.interfaces.nsIIOService);                   
       var ch = ios.newChannel("http://www.apple.com/", null, null);                 

       var listener = {                            
        QueryInterface : XPCOMUtils.generateQI([Ci.nsIChannelEventSink]),               
        onDataAvailable: function() {},                       
        onStopRequest: function() {},                        
        onStartRequest: function() {}                        
       };                                

       ch.asyncOpen(listener,null);                         

       var eventSink = request.notificationCallbacks.getInterface(Ci.nsIChannelEventSink);           
       eventSink.asyncOnChannelRedirect(request,ch,Ci.nsIChannelEventSink.REDIRECT_INTERNAL,function() {});       
      } 
3

हम एक नए के साथ nsiHttpChannel अधिभावी करके ऐसा कर सकते कर इस थोड़ा जटिल है लेकिन सौभाग्य से ऐड-ऑन https-everywhere लागू करता है यह एक मजबूर करने के लिए:

यहाँ मैं क्या कोशिश कर रहा था की मूल बातें है https कनेक्शन

https-everywhere के स्रोत कोड उपलब्ध है here

इस के लिए आवश्यक कोड के अधिकांश फाइलों में है

[IO Util.js] [ChannelReplacement.js]

हम अकेले ऊपर फाइलों के साथ काम कर सकते हैं बशर्ते हमारे पास सीसी, सीआई सेट अप और फंक्शन 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(); 

कोड अनुरोध को रीडायरेक्ट नहीं की जगह लेगा।

जबकि मैंने उपर्युक्त कोड का पर्याप्त परीक्षण किया है, मुझे इसके कार्यान्वयन के बारे में निश्चित नहीं है। जहां तक ​​मैं बाहर कर सकता हूं, यह अनुरोधित चैनल के सभी विशेषताओं की प्रतिलिपि बनाता है और उन्हें ओवरराइड करने के लिए चैनल पर सेट करता है। जिसके बाद मूल अनुरोध द्वारा अनुरोधित आउटपुट को नए चैनल का उपयोग करके आपूर्ति की जाती है।

पीएस मैंने एक एसओ पोस्ट देखा था जिसमें इस दृष्टिकोण का सुझाव दिया गया था।

+0

क्या आप कृपया कुछ लापता फ़ंक्शंस प्रदान कर सकते हैं जैसे isToBeReplace और ChannelReplacement – Noitidart

+0

isToBeReplace आपका तर्क है जिसे तय करना चाहिए कि रीडायरेक्ट करना है या नहीं। ChannelReplacement को ChannelReplacement.js – mdprasadeng

+0

में परिभाषित किया गया है उत्तर के लिए @mdprasadeng बहुत धन्यवाद, मुझे चिंता थी कि संदेश आपको नहीं मिलेगा। isToBeReplace मैं इसे बहुत समझ सकता हूं, लेकिन क्या आप कृपया चैनलReplacement.js से लिंक कर सकते हैं उपर्युक्त लिंक – Noitidart

0

मैंने इसे इस तरह से किया है: nsIHttpChannel"http-on-modify-request" ईवेंट पर रोकें, वर्तमान विंडो के लिए ब्राउज़र ऑब्जेक्ट प्राप्त करें, browser.loadURI पर कॉल करें।

var utils = require("sdk/window/utils"); 

function needsRedirect(url) { 
    // to be implemented 
    return true; 
} 

function generateNewUrl(url) { 
    // to be implemented 
    return "http://www.example.com/"; 
} 

Cc["@mozilla.org/observer-service;1"] 
    .getService(Ci.nsIObserverService) 
    .addObserver({ 
     observe: function(subject, topic, data) { 
      var channel = subject.QueryInterface(Ci.nsIHttpChannel); 
      var url = channel.originalURI.spec; 
      if (needsRedirect(url)) { 
       //stop 
       channel.cancel(Cr.NS_BINDING_ABORTED); 

       //redirect 
       var gBrowser = utils.getMostRecentBrowserWindow().gBrowser; 
       var domWin = channel.notificationCallbacks.getInterface(Ci.nsIDOMWindow); 
       var browser = gBrowser.getBrowserForDocument(domWin.top.document); 
       browser.loadURI(generateNewUrl(url)); 

      } 
     } 
    }, "http-on-modify-request", false); 
+0

यह कोड नहीं लगता है उम्मीद के अनुसार काम करने के लिए। जब ​​मैं इस कोड को उस वेबसाइट पर लागू करता हूं जिसमें छवियां हैं, तो यह कॉल छवि पर बनाई जाएगी, और इसलिए वर्तमान लोड किए गए पृष्ठ को URL उत्पन्न करने के बजाय प्रतिस्थापित किया जाएगा NewUrl ("image.jpg") उत्पन्नNewUrl ("index.html")। मुझे लगता है कि 'channel.redirectTo (nsUrl)' एक बेहतर तरीका है। –

0

कुछ परीक्षण जब मैं चैनल प्रतिस्थापन तर्क अन्य उत्तर में उल्लेख का एक संक्षिप्त संस्करण (देखें this gist) बनाया।

सामान्य विचार सभी महत्वपूर्ण गुणों को नए चैनल पर स्थानांतरित करने के लिए प्रतीत होता है, पुराने चैनल से कॉलबैक हटा दें ताकि मैनिप्लेशंस पृष्ठ लोड को यात्रा न करें और फिर पुराने चैनल को बंद कर दें।

कुछ संशोधनों के साथ कोई दस्तावेज़ लोड के लिए पृष्ठ यूआरआई बदल सकता है या इसे छोड़ सकता है।

चेतावनी: कुछ पेज लोड करने के लिए यह एक त्वरित हैक था, मैंने इसे गहराई से परीक्षण नहीं किया है और यह शायद कुछ मामलों के लिए तोड़ देगा। मुझे संदेह है कि एचटीटीपीएस हर जगह अधिक जटिल क्यों हैं।

संबंधित मुद्दे