2009-05-30 9 views
2

Fond
J'ai une extension existante conçue pour accompagner un jeu basé sur un navigateur (l'extension est à moi, le jeu ne l'est pas). L'extension avait été en train de gratter les pages au fur et à mesure qu'elles arrivaient pour les données dont elle avait besoin et de faire des requêtes ajax pour prendre des mesures.Comment faire un addon Firefox écouter xmlhttprequests à partir d'une page?

Problème
Les développeurs de jeux ont récemment changé un certain nombre d'actions sur le site pour utiliser ajax demandes et je suis jusqu'ici incapable d'obtenir les données de ces demandes.

Ce que j'ai jusqu'à présent

function TracingListener() { 
} 

TracingListener.prototype = 
{ 
    originalListener: null, 
    receivedData: [], // array for incoming data. 

    onDataAvailable: function(request, context, inputStream, offset, count) 
    { 
     var binaryInputStream = CCIN("@mozilla.org/binaryinputstream;1", 
       "nsIBinaryInputStream"); 
     var storageStream = CCIN("@mozilla.org/storagestream;1", "nsIStorageStream"); 
     binaryInputStream.setInputStream(inputStream); 
     storageStream.init(8192, count, null); 

     var binaryOutputStream = CCIN("@mozilla.org/binaryoutputstream;1", 
       "nsIBinaryOutputStream"); 

     binaryOutputStream.setOutputStream(storageStream.getOutputStream(0)); 

     // Copy received data as they come. 
     var data = binaryInputStream.readBytes(count); 

     this.receivedData.push(data); 

     binaryOutputStream.writeBytes(data, count); 
     this.originalListener.onDataAvailable(request, context,storageStream.newInputStream(0), offset, count); 
    }, 

    onStartRequest: function(request, context) { 
     this.originalListener.onStartRequest(request, context); 
    }, 

    onStopRequest: function(request, context, statusCode) 
    { 
     try { 
      if (request.originalURI && piratequesting.baseURL == request.originalURI.prePath && request.originalURI.path.indexOf("/index.php?ajax=") == 0) { 

       dump("\nProcessing: " + request.originalURI.spec + "\n"); 
       var date = request.getResponseHeader("Date"); 

       var responseSource = this.receivedData.join(); 
       dump("\nResponse: " + responseSource + "\n"); 

       piratequesting.ProcessRawResponse(request.originalURI.spec, responseSource, date); 
      } 
     } catch(e) { dumpError(e);} 

     this.originalListener.onStopRequest(request, context, statusCode); 
    }, 

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


hRO = { 

    observe: function(aSubject, aTopic, aData){ 
     try { 
      if (aTopic == "http-on-examine-response") { 
       if (aSubject.originalURI && piratequesting.baseURL == aSubject.originalURI.prePath && aSubject.originalURI.path.indexOf("/index.php?ajax=") == 0) { 
        var newListener = new TracingListener(); 
        aSubject.QueryInterface(Ci.nsITraceableChannel); 
        newListener.originalListener = aSubject.setNewListener(newListener); 

        dump("\n\nObserver Processing: " + aSubject.originalURI.spec + "\n"); 
        for (var i in aSubject) { 
         dump("\n\trequest." + i); 
        } 
       } 
      } 
     } catch (e) { 
      dumpError(e); 

     } 
    }, 

    QueryInterface: function(aIID){ 
     if (aIID.equals(Ci.nsIObserver) || 
     aIID.equals(Ci.nsISupports)) { 
      return this; 
     } 

     throw Components.results.NS_NOINTERFACE; 

    } 
}; 


var observerService = Cc["@mozilla.org/observer-service;1"] .getService(Ci.nsIObserverService); 

observerService.addObserver(hRO, "http-on-examine-response", false); 

Qu'est-ce qui se passe
Le code ci-dessus est informé correctement lorsqu'une demande HTTP est traitée. L'uri est également disponible et correct (il passe le contrôle domain/path) mais le responseSource qui est sauvegardé est, pour autant que je sache, toujours le contenu de la première requête http faite après l'ouverture du navigateur et, évidemment, pas ce que je m'attendais.

Le code ci-dessus provient en grande partie de . J'espère vraiment que c'est quelque chose de petit que j'ai oublié, mais je me suis cogné la tête contre le bureau pendant des jours sur celui-ci, et maintenant je me tourne vers la sagesse de SO. Des idées?

Répondre

3

mais le responseSource qui obtient sous-évaluées est, pour autant que je peux dire, toujours le contenu de la première http demande faite après que le navigateur ouvert et, évidemment, pas ce que je attendre.

Il y a un problème avec le code ci-dessus. Le membre "receivedData" est déclaré sur l'objet prototype et le tableau vide est affecté. Cela conduit à chaque instanciation de la classe TracingListener à utiliser le même objet en mémoire pour receivedData. Changer votre code pour résoudre le problème:

function TracingListener() { 
    this.receivedData = []; 
} 

TracingListener.prototype = 
{ 
    originalListener: null, 
    receivedData: null, // array for incoming data. 

/* skipped */ 

} 

Vous ne savez pas si cela va résoudre votre problème d'origine.

+0

+1 mon dieu, tu avais raison. J'avais eu le même insecte il y a des mois et je l'avais juste oublié. L'astuce consistait à assigner le tableau à onStartRequest. –

+0

l'affecter dans le constructeur fonctionne également (bien sûr), l'assigner dans onStartRequest assure simplement que l'affectation ne se produit pas prématurément –

Questions connexes