2010-01-26 24 views
6

Cập nhật: Tôi đoán chủ thể đưa ra một quan niệm sai lầm rằng tôi đang tìm kiếm một addon hiện có. Đây là một vấn đề tùy chỉnh và tôi KHÔNG muốn một giải pháp hiện có.
Tôi muốn VIẾT (hoặc thích hợp hơn, sửa đổi và tồn tại) Addon.Tạo Firefox Addon để Xem và sửa đổi các yêu cầu XHR & reponses

Dưới đây là yêu cầu của tôi:

  • Tôi muốn addon của tôi để làm việc cho một trang web cụ thể chỉ
  • Các dữ liệu trên các trang được mã hóa bằng cách sử dụng băm 2 cách
  • Một thỏa thuận tốt về thông tin được tải bởi các yêu cầu XHR và đôi khi được hiển thị trong các bong bóng hoạt hình, v.v.
  • Phiên bản hiện tại của trình bổ sung phân tích trang qua biểu thức XPath , giải mã dữ liệu và thay thế chúng

  • vấn đề này được đưa ra với những hộp bubblified được hiển thị về sự kiện mouse-over

  • Do đó, tôi nhận ra rằng nó có thể là một ý tưởng tốt để tạo ra một XHR cầu mà có thể nghe tất cả các dữ liệu và giải mã/mã hóa một cách nhanh chóng
  • Sau một vài lần tìm kiếm, tôi đã xem qua nsITraceableInterface [1] [2] [3]

Chỉ cần muốn biết nếu tôi đi trên con đường đúng. Nếu "có", vui lòng cung cấp thêm bất kỳ gợi ý và gợi ý nào có thể thích hợp; và nếu "Không", thì .. tốt, vui lòng trợ giúp với các con trỏ chính xác :)

Cảm ơn,
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/

Trả lời

8

nsITraceableChannel thực sự là con đường để đi đây. bài đăng trên blog của Jan Odvarko (softwareishard.com) và bản thân tôi (ashita.org) cho thấy cách thực hiện điều này. Bạn cũng có thể muốn xem http://www.ashita.org/implementing-an-xpcom-firefox-interface-and-creating-observers/, tuy nhiên nó không thực sự cần thiết để làm điều này trong một thành phần XPCOM.

Các bước cơ bản:

  1. Tạo mẫu Object thực hiện nsITraceableChannel; và tạo người quan sát để nghe http: // yêu cầu sửa đổi và http-on-kiểm tra-phản ứng
  2. người quan sát đăng ký
  3. người quan sát nghe hai loại yêu cầu thêm đối tượng nsITraceableChannel của chúng tôi vào chuỗi người nghe và đảm bảo rằng nsITC biết ai là tiếp theo trong chuỗi
  4. đối tượng
  5. nsITC cung cấp ba callbacks và mỗi sẽ được gọi là ở giai đoạn thích hợp: onStartRequest, onDataAvailable, và onStopRequest
  6. trong mỗi callbacks trên, đối tượng nsITC của chúng ta phải vượt qua trên các dữ liệu mục tiếp theo trong chuỗi

Dưới đây là mã thực tế từ tiện ích bổ sung theo trang web cụ thể mà tôi đã viết có hành vi rất giống với của bạn từ những gì tôi có thể nói.

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

Trong đoạn mã trên, originalListener là người nghe chúng tôi đang tự chèn vào trước trong chuỗi. Điều quan trọng là bạn giữ thông tin đó khi tạo Trình theo dõi và truyền dữ liệu trong cả ba cuộc gọi lại. Nếu không thì không có gì sẽ hoạt động (các trang thậm chí sẽ không tải. Firefox chính nó là cuối cùng trong chuỗi).

Lưu ý: có một số chức năng được gọi là trong đoạn mã trên là một phần của các piratequesting add-on, ví dụ .: parseQuery()dumpError()

0

Tamper Data Add-on. Xem thêm các trang How to Use it

+0

Các chủ đề đã cho bạn một ý tưởng sai lầm, có lẽ. Tôi không tìm kiếm giải pháp hiện có. Vui lòng đọc toàn bộ vấn đề. Cảm ơn :) – Jumper

+0

@ Jumper, Tamper Data có thể là cơ sở tốt để bắt đầu xây dựng tiện ích bổ sung của bạn. Bạn sẽ phải tách ra hầu hết mã UI, nhưng mã bạn cần theo dõi và thay đổi các yêu cầu XHR sẽ ở trong đó. –

+0

Vâng, có một cái nhìn lướt qua trong quá khứ. Dường như sử dụng dịch vụ Observer. Các liên kết trong câu hỏi (nói về nsITraceableChannel) cũng sử dụng Observer. Sẽ xem lại mã tamperData hôm nay. – Jumper

0

Bạn có thể thử tạo một tập lệnh viết tắt và ghi đè XMLHttpRequest.
Mã này sẽ giống như thế:

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

Cũng lưu ý rằng bạn có thể biến một kịch bản GM vào một addon cho Firefox

+0

Tôi đã xem xét điều đó nhưng quyết định tránh vì không an toànWindow được coi là không an toàn. Bất kỳ ý tưởng nào về kênh không thể truy cập được? – Jumper

+0

unsafeWindow chỉ là một vấn đề nếu bạn có mã nghèo. Dựa trên âm thanh của câu hỏi của bạn, tôi nghĩ rằng bạn nên được ok bằng cách sử dụng unsafeWindow. Lý do duy nhất không sử dụng nó sẽ là nếu bạn cảm thấy rằng trang web này sẽ được sử dụng trên sẽ cố gắng bằng cách nào đó để trở lại hack hệ thống của bạn (điều này sẽ không xảy ra nếu bạn không phát hành mã, và thậm chí nếu bạn làm, nó sẽ phải nhận được rất nhiều việc sử dụng trước khi họ có thể quan tâm nhất), ngay cả khi họ đã hack bạn một số cách, mã của bạn phải đủ an toàn để xử lý nó. Nếu bạn đang lo lắng về điều này hơn một FF addon sẽ tồi tệ hơn. –

Các vấn đề liên quan