43 votes

Requête de redirection (nsiHttpChannel?) Dans les extensions Firefox

J'ai essayé à ce pour un long moment maintenant, et pas de bons résultats.

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);

En gros, sur http-on-modify-request, je sais comment examiner l'URI, figure qui de la fenêtre (le cas échéant) auquel il est associé, et un tas d'autres trucs. Ce que je ne peux pas savoir comment rediriger une requête, dont je sais qu'il est possible à partir d'ici, parce que je peux obtenir un nsIHttpChannel avant toute demande est jamais envoyé.

Quelqu'un sait quoi faire? :/ J'ai essayé pour un couple de semaines, sur et en dehors, et a obtenu nulle part.

3voto

mdprasadeng Points 48

Nous pouvons le faire en remplaçant l' nsiHttpChannel par un nouveau, en fait c'est un peu compliqué mais heureusement, l'add-on https-everywhere met en œuvre pour forcer une connexion https.

https-everywheres'code source est disponible ici

La plupart du code nécessaire pour cela est dans les fichiers

[IO Util.js] [ChannelReplacement.js]

Nous pouvons travailler avec les fichiers ci-dessus, seul, pourvu que nous ayons la base des variables comme les Cc,de Ci, de configurer et de la fonction xpcom_generateQI défini.

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();

Le code de remplacer la demande de ne pas rediriger.

Alors, j'ai testé le code ci-dessus assez bien, je ne suis pas sûr au sujet de sa mise en œuvre. Aussi loin que je peux faire, il copie tous les attributs de la demande de canal et la met à la chaîne pour être substituée. Après avoir quelque peu la sortie demandée par la demande d'origine est fourni à l'aide de la nouvelle chaîne.

P. S. j'avais vu un post dans lequel cette approche a été suggérée.

1voto

Daniel Points 643

J'ai l'impression que vous ne pouvez pas le faire à ce niveau - j'ai essayé une variété de méthodes de l'extérieur "tromper" le code qui appelle pour un nsIHttpChannel d'être créé (exemple à la fin du post).

Ce que je recommande est que si vous voulez une redirection, contactez le canal de la fenêtre du propriétaire (qui fonctionne 99% du temps), et le charger de redirection. Je sais que ça ne va pas se comporter de la même chose, mais comme je ne sais pas exactement pourquoi vous ne le faites pas, ce sera à l'extérieur (pour l'utilisateur) semblent être en train de faire la même chose que ce que vous demandez.

Voici les bases de ce que j'ai essayé:

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() {});                          
            } 

0voto

fbenariac Points 41

Avez-vous essayé d'appeler la méthode nsIChannel.cancel lors de l'écoute d'événements de redirection?

0voto

vadimrostok Points 61

Je l'ai fait ainsi: arrêtez les événements nsIHttpChannel sur "http-on-modify-request" , obtenez un objet de navigateur pour la fenêtre en cours, appelez 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);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X