我正在尝试按照"Ashita"所述实现基本的XHR侦听器,但是当使用扩展名加载firefox时,每当页面尝试加载时都会收到此错误,这会阻止加载任何内容:{{1} }
我的overlay.js是:
if (typeof Cc == "undefined") { var Cc = Components.classes; } if (typeof Ci == "undefined") { var Ci = Components.interfaces; } if (typeof CCIN == "undefined") { function CCIN(cName, ifaceName){ return Cc[cName].createInstance(Ci[ifaceName]); } } if (typeof CCSV == "undefined") { function CCSV(cName, ifaceName){ if (Cc[cName]) // if fbs fails to load, the error can be _CC[cName] has no properties return Cc[cName].getService(Ci[ifaceName]); else dump("CCSV fails for cName:" + cName); }; } var httpRequestObserver = { observe: function(request, aTopic, aData){ if (aTopic == "http-on-examine-response") { var newListener = new TracingListener(); request.QueryInterface(Ci.nsITraceableChannel); newListener.originalListener = request.setNewListener(newListener); } }, QueryInterface: function(aIID){ if (aIID.equals(Ci.nsIObserver) || aIID.equals(Ci.nsISupports)) { return this; } throw Components.results.NS_NOINTERFACE; }, }; function TracingListener() { this.receivedData = []; //initialize the array } TracingListener.prototype = { originalListener: null, receivedData: null, //will be an array for incoming data. onDataAvailable: function(request, context, inputStream, offset, count) { var binaryInputStream = CCIN("@mozilla.org/binaryinputstream;1", "nsIBinaryInputStream"); binaryInputStream.setInputStream(inputStream); var storageStream = CCIN("@mozilla.org/storagestream;1", "nsIStorageStream"); //8192 is the segment size in bytes, count is the maximum size of the stream in bytes 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); //Pass it on down the chain this.originalListener.onDataAvailable(request, context, inputStream, offset, count); }, onStartRequest: function(request, context) { this.originalListener.onStartRequest(request, context); }, onStopRequest: function(request, context, statusCode) { try { //QueryInterface into HttpChannel to access originalURI and requestMethod properties request.QueryInterface(Ci.nsIHttpChannel); var data = null; if (request.requestMethod.toLowerCase() == "post") { var postText = this.readPostTextFromRequest(request, context); if (postText) data = ((String)(postText)).parseQuery(); } //Combine the response into a single string var responseSource = this.receivedData.join(''); //fix leading spaces bug //(FM occasionally adds spaces to the beginning of their ajax responses... //which breaks the XML) responseSource = responseSource.replace(/^\s+(\S[\s\S]+)/, "$1"); //gets the date from the response headers on the request. //For PirateQuesting this was preferred over the date on the user's machine var date = Date.parse(request.getResponseHeader("Date")); //Again a PQ specific function call, but left as an example. //This just passes a string URL, the text of the response, //the date, and the data in the POST request (if applicable) /* piratequesting.ProcessRawResponse(request.originalURI.spec, responseSource, date, data); */ dump(date); dump(data); dump(responseSource); } catch (e) { //standard function to dump a formatted version of the error to console dump(e); } this.originalListener.onStopRequest(request, context, statusCode); }, 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); 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) { dump(exc); } return null; }, QueryInterface: function (aIID) { if (aIID.equals(Ci.nsIStreamListener) || aIID.equals(Ci.nsISupports)) { return this; } throw Components.results.NS_NOINTERFACE; }, 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; } } var observerService = Cc["@mozilla.org/observer-service;1"] .getService(Ci.nsIObserverService); observerService.addObserver(httpRequestObserver, "http-on-examine-response", false); dump("WTFBBQ");
非常感谢任何帮助。
答案 0 :(得分:1)
使用较少的代码,我似乎工作得很好。尝试用以下代码替换onDataAvailable函数代码:
var binaryInputStream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
binaryInputStream.setInputStream(inputStream);
this.receivedData.push(binaryInputStream.readBytes(count));