2010-11-04 18 views
5

Bir firefox eklentisi üzerinde çalışıyorum ve bir sayfanın xhr isteğini başlattığını, birkaç kod gördüklerini, ancak oldukça büyük olduklarını bilmek istiyorum, bunu başarmak için basit bir örnek var mı?javascript ile xhr isteklerini kolayca nasıl dinleyebilirim?

Bu kodu test ediyorum: içinde

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

TracingListener.prototype = 
{ 
    originalListener: null, 
    receivedData: null, // 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); 
     //var data = inputStream.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.receivedData = []; 
     this.originalListener.onStartRequest(request, context); 
    }, 

    onStopRequest: function(request, context, statusCode) 
    { 
     try 
     { 
      request.QueryInterface(Ci.nsIHttpChannel); 

      if (request.originalURI && piratequesting.baseURL == request.originalURI.prePath && request.originalURI.path.indexOf("/index.php?ajax=") == 0) 
      { 

       var data = null; 
       if (request.requestMethod.toLowerCase() == "post") 
       { 
        var postText = this.readPostTextFromRequest(request, context); 
        if (postText) 
         data = ((String)(postText)).parseQuery(); 

       } 
       var date = Date.parse(request.getResponseHeader("Date")); 
       var responseSource = this.receivedData.join(''); 

       //fix leading spaces bug 
       responseSource = responseSource.replace(/^\s+(\S[\s\S]+)/, "$1"); 

       piratequesting.ProcessRawResponse(request.originalURI.spec, responseSource, date, data); 
      } 
     } 
     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; 
    }, 
    readPostTextFromRequest : function(request, context) { 
     try 
     { 
      var is = request.QueryInterface(Ci.nsIUploadChannel).uploadStream; 
      if (is) 
      { 
       var ss = is.QueryInterface(Ci.nsISeekableStream); 
       var prevOffset; 
       if (ss) 
       { 
        prevOffset = ss.tell(); 
        ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0); 
       } 

       // Read data from the stream.. 
       var charset = "UTF-8"; 
       var text = this.readFromStream(is, charset, true); 

       // Seek locks the file so, seek to the beginning only if necko hasn't read it yet, 
       // since necko doesn't seek to 0 before reading (at lest not till 459384 is fixed). 
       if (ss && prevOffset == 0) 
        ss.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0); 

       return text; 
      } 
      else { 
       dump("Failed to Query Interface for upload stream.\n"); 
      } 
     } 
     catch(exc) 
     { 
      dumpError(exc); 
     } 

     return null; 
    }, 
    readFromStream : function(stream, charset, noClose) { 

     var sis = CCSV("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream"); 
     sis.setInputStream(stream); 

     var segments = []; 
     for (var count = stream.available(); count; count = stream.available()) 
      segments.push(sis.readBytes(count)); 

     if (!noClose) 
      sis.close(); 

     var text = segments.join(""); 
     return text; 
    } 

} 


hRO = { 

    observe: function(request, aTopic, aData){ 
     try { 
      if (typeof Cc == "undefined") { 
       var Cc = Components.classes; 
      } 
      if (typeof Ci == "undefined") { 
       var Ci = Components.interfaces; 
      } 
      if (aTopic == "http-on-examine-response") { 
       request.QueryInterface(Ci.nsIHttpChannel); 

       //if (request.originalURI && piratequesting.baseURL == request.originalURI.prePath) { 
        // var newListener = new TracingListener(); 
        //request.QueryInterface(Ci.nsITraceableChannel); 
        //newListener.originalListener = request.setNewListener(newListener); 
       //} GOOGLE FAILS TO LOAD IF I UNCOMMENT THIS 
      } 
     } catch (e) { 
      dump("\nhRO error: \n\tMessage: " + e.message + "\n\tFile: " + e.fileName + " line: " + e.lineNumber + "\n"); 
     } 
    }, 

    QueryInterface: function(aIID){ 
     if (typeof Cc == "undefined") { 
      var Cc = Components.classes; 
     } 
     if (typeof Ci == "undefined") { 
      var Ci = Components.interfaces; 
     } 
     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); 

Ama newListener eklerken (anlık arama özelliği ile) google gibi o kısmı siteleri yorumsuz hiç değilse, alışkanlık yükü gözlemlemek, ben edebilmek istiyorum onStopRequest üzerindeki responseSource'u okumak için bir uyarı eklemeye çalıştım ancak hiçbir zaman patlamıyor ve sitelerin google anlık arama ile gerçekleştiğini söylediğim gibi dağınık.

cevap

6

Javascript'te, herhangi bir işlevi veya nesneyi anında yeniden tanımlayabilirsiniz. Sorununuz için şu şekilde deneyebilirsiniz:

var original_xhr = XMLHttpRequest; 
XMLHttpRequest = function() { 
    /* logic that notifies your plugin goes here */ 
    ... 
    original_xhr(); 
    alert ("I redefined this function"); 

Bu yardımcı olur umarım. -tjw

+0

Bu, google canlı arama özelliği için istek yakalamıyor, xhr'den farklı bir şey kullandığını biliyor musunuz? – gtilx

+2

Evet, Google, document.write() kullanarak sayfaya bir komut dosyası etiketi yerleştiren JSONP'a benzer bir şey kullanır. Yani google için document.write() işlevinin üzerine yazacaksınız. Bazı JSONP uygulamaları document.appendChild (script_tag) kullanır. –

3

İşte Travis J Webb çözümün tam sürümüdür. Bunu sadece JS veya HMTL dosyanızın üstüne koyun.

(function(){ 
    var original_xhr = XMLHttpRequest; 
    window.XMLHttpRequest = function() { 
     /* logic that notifies your plugin goes here */ 

     original_xhr.apply(this, Array.prototype.slice.call(arguments)); 
     alert ("I redefined this function"); 
    } 
}()); 
+0

Bu, google canlı arama özelliği için istek yakalamıyor, xhr'den farklı bir şey kullandığını biliyor musunuz? – gtilx

+0

Güncellenen kodu FireFox 3.6.3 ve Firebug ile çalıştırdım ve bu istekleri yakaladı, ancak Google'ın kodunda bir javascript hatası da görüntüledi. Bu durum, iyileştirilmesi gereken bir yer olduğuna inanmaktır. – Eric

İlgili konular