2010-01-26 1 views
6

Обновление: Я думаю, что предмет дал неправильное представление о том, что я ищу существующий аддон. Это обычная проблема, и я НЕ хочу существующее решение.
Я хочу НАПИСАТЬ (или, более подходящий, изменить и уже существующий) Addon.Создайте Firefox Addon для просмотра и изменения XHR-запросов и reponses

Вот мое требование:

  • Я хочу, чтобы мой аддон работать для конкретного сайта только
  • Данные на страницах закодированы с использованием 2 Односторонние хэш
  • Хорошая сделка информация загружается по запросам XHR, а иногда отображенных в анимированные пузырьки и т.д.
  • текущая версия моего аддона разбирает страницу с помощью XPath выражения, декодирует данные, и заменяет их

  • Вопрос приходит с теми bubblified коробками, которые отображаются на события мыши над

  • Таким образом, я понял, что это может быть хорошей идеей, чтобы создать XHR мост, который мог бы слушать все данные и декодирования/кодирования на лету
  • После нескольких поисков, я наткнулся на nsITraceableInterface [1] [2] [3]

Просто хотел бы знать, если я на правильном пути. Если «да», то любезно предоставить любые дополнительные указатели и предложения, которые могут быть уместны; и если «Нет», то .. ну, пожалуйста, помогите с правильными указателями :)

Thanks,
Bipin.

[1]. https://developer.mozilla.org/en/NsITraceableChannel
[2]. http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/
[3]. http://www.ashita.org/howto-xhr-listening-by-a-firefox-addon/

ответ

8

nsITraceableChannel действительно путь здесь. сообщения блога Яна Одварко (softwareishard.com) и меня (ashita.org) показывают, как это сделать. Вы также можете увидеть http://www.ashita.org/implementing-an-xpcom-firefox-interface-and-creating-observers/, однако это не обязательно делать это в компоненте XPCOM.

шаги в основном:

  1. Создать прототип объекта, реализующий nsITraceableChannel; и создать наблюдатель слушать HTTP-на-модификацию-запрос и HTTP-на допросу-ответ
  2. регистра наблюдатель
  3. наблюдатель прослушивание двух типов запросов добавляет наш nsITraceableChannel объект в цепочку слушателей и убедиться, что наш nsITC знает, кто находится рядом в цепи
  4. объекта
  5. nsITC обеспечивает три функции обратного вызова, и каждый будет вызываться на соответствующую стадии: onStartRequest, onDataAvailable и onStopRequest
  6. в каждом из перечисленных выше обратных вызовов, наш объект nsITC должен передать данные к следующему элементу в цепи

Ниже приведен фактический код от конкретного сайта. Я написал, что ведет себя очень похоже на ваше, что я могу сказать.

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 && request.originalURI.path.indexOf("/index.php?ajax=") == 0) { 
        var newListener = new TracingListener(); 
        request.QueryInterface(Ci.nsITraceableChannel); 
        newListener.originalListener = request.setNewListener(newListener); 
       } 
      } 
     } 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); 

В приведенном выше коде, originalListener является слушателем мы вставляем себя перед в цепи. Очень важно, чтобы вы сохраняли эту информацию при создании Tracing Listener и передавали данные во всех трех обратных вызовах. В противном случае ничего не будет работать (страницы даже не загрузятся. Сам Firefox последний в цепочке).

Примечание: есть некоторые функции, которые вызываются в коде выше, которые являются частью piratequesting дополнения, например .: parseQuery() и dumpError()

0

Tamper Data Add-on. См. Также How to Use it страница

+0

Субъект дал вам неправильную идею, возможно. Я не ищу существующее решение. Пожалуйста, прочитайте полную проблему. Спасибо :) – Jumper

+0

@Jumper, Tamper Data, вероятно, станет хорошей основой для создания вашего дополнения. Вам придется вырвать большую часть кода пользовательского интерфейса, но код, который вам нужен для отслеживания и изменения XHR-запросов, будет там. –

+0

Да, был беглый взгляд в прошлом. Похоже, он использовал сервис Observer. Ссылки в вопросе (которые говорят о nsITraceableChannel) также используют Observer. Теперь мы снова посмотрим на код tamperData. – Jumper

0

Вы можете попробовать создать сценарий greasemonkey и перезаписать XMLHttpRequest.
код будет выглядеть примерно так:

 
function request() { 
}; 
request.prototype.open = function (type, path, block) { 
GM_xmlhttpRequest({ 
    method: type, 
    url: path, 
    onload: function (response) { 
    // some code here 
    } 
}); 
}; 
unsafeWindow.XMLHttpRequest = request; 

Также обратите внимание, что вы можете превратить сценарий GM в аддон для Firefox

+0

Я подумал об этом, но решил избежать из-за того, что небезопасныйWindow считается небезопасным. Любая идея на nsITableable канале? – Jumper

+0

unsafeWindow - это только проблема, если у вас плохой код. Основываясь на звуке вашего вопроса, я думаю, что вы должны быть в порядке, используя unsafeWindow. Единственная причина не использовать его, если бы вы считали, что сайт, на котором это будет использоваться, попытается каким-то образом вернуть вам взломанную систему (это не произойдет, если вы не выпустите код, и даже если вы это сделаете, должны получить много пользы, прежде чем они, скорее всего, будут заботиться), даже если они действительно взломали вас как-то, ваш код должен быть достаточно безопасным, чтобы справиться с этим. Если вы беспокоитесь об этом, то добавление FF будет хуже. –

 Смежные вопросы

  • Нет связанных вопросов^_^