NS_ERROR_FAILURE

时间:2010-01-30 07:34:17

标签: javascript firefox-addon

我正在尝试按照"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");

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

使用较少的代码,我似乎工作得很好。尝试用以下代码替换onDataAvailable函数代码:

    var binaryInputStream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
    binaryInputStream.setInputStream(inputStream);
    this.receivedData.push(binaryInputStream.readBytes(count));